diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..ac909da --- /dev/null +++ b/.clang-format @@ -0,0 +1,160 @@ +Language: Cpp +# BasedOnStyle: LLVM +# 访问说明符(public、private等)的偏移 +AccessModifierOffset: -4 +# 开括号(开圆括号、开尖括号、开方括号)后的对齐 +AlignAfterOpenBracket: Align +# 连续赋值时,等号对齐 +AlignConsecutiveAssignments: false +# 连续赋值时,变量名对齐 +AlignConsecutiveDeclarations: false +# 左对齐逃脱换行(使用反斜杠换行)的反斜杠 +AlignEscapedNewlinesLeft: true +# 水平对齐二元和三元表达式的操作数 +AlignOperands: true +# 对齐连续的尾随的注释 +AlignTrailingComments: true +# 允许函数声明的所有参数在放在下一行 +AllowAllParametersOfDeclarationOnNextLine: false +# 允许短的块放在同一行 +AllowShortBlocksOnASingleLine: false +# 允许短的case标签放在同一行 +AllowShortCaseLabelsOnASingleLine: false +# 允许短的函数放在同一行: None, InlineOnly(定义在类中), Empty(空函数), Inline(定义在类中,空函数), All +AllowShortFunctionsOnASingleLine: Empty +# 允许短的if语句保持在同一行 +AllowShortIfStatementsOnASingleLine: false +# 允许短的循环保持在同一行 +AllowShortLoopsOnASingleLine: false +# 总是在定义返回类型后换行(deprecated) +AlwaysBreakAfterDefinitionReturnType: None +# 总是在返回类型后换行: None, All, TopLevel(顶级函数,不包括在类中的函数), +# AllDefinitions(所有的定义,不包括声明), TopLevelDefinitions(所有的顶级函数的定义) +AlwaysBreakAfterReturnType: None +# 总是在多行string字面量前换行 +AlwaysBreakBeforeMultilineStrings: true +# 总是在template声明后换行 +AlwaysBreakTemplateDeclarations: false +# false表示函数实参要么都在同一行,要么都各自一行 +BinPackArguments: true +# false表示所有形参要么都在同一行,要么都各自一行 +BinPackParameters: false +# 大括号换行,只有当BreakBeforeBraces设置为Custom时才有效 +BraceWrapping: + AfterClass: false + AfterControlStatement: false + AfterEnum: false + AfterFunction: true + AfterNamespace: false + AfterObjCDeclaration: false + AfterStruct: false + AfterUnion: false + BeforeCatch: false + BeforeElse: false + IndentBraces: false +# 在二元运算符前换行: None(在操作符后换行), NonAssignment(在非赋值的操作符前换行), All(在操作符前换行) +BreakBeforeBinaryOperators: None +# 在大括号前换行: Attach(始终将大括号附加到周围的上下文), Linux(除函数、命名空间和类定义,与Attach类似), +# Mozilla(除枚举、函数、记录定义,与Attach类似), Stroustrup(除函数定义、catch、else,与Attach类似), +# Allman(总是在大括号前换行), GNU(总是在大括号前换行,并对于控制语句的大括号增加额外的缩进), WebKit(在函数前换行), Custom +# 注:这里认为语句块也属于函数 +BreakBeforeBraces: Custom +# 在三元运算符前换行 +BreakBeforeTernaryOperators: false +# 在构造函数的初始化列表的逗号前换行 +BreakConstructorInitializersBeforeComma: false +# 每行字符的限制,0表示没有限制 +ColumnLimit: 120 +# 描述具有特殊意义的注释的正则表达式,它不应该被分割为多行或以其它方式改变 +CommentPragmas: "^ IWYU pragma:" +# 构造函数的初始化列表要么都在同一行,要么都各自一行 +ConstructorInitializerAllOnOneLineOrOnePerLine: true +# 构造函数的初始化列表的缩进宽度 +ConstructorInitializerIndentWidth: 4 +# 延续的行的缩进宽度 +ContinuationIndentWidth: 4 +# 去除C++11的列表初始化的大括号{后和}前的空格 +Cpp11BracedListStyle: true +# 继承最常用的指针和引用的对齐方式 +DerivePointerAlignment: false +# 关闭格式化 +DisableFormat: false +# 自动检测函数的调用和定义是否被格式为每行一个参数(Experimental) +ExperimentalAutoDetectBinPacking: false +# 需要被解读为foreach循环而不是函数调用的宏 +ForEachMacros: [foreach, Q_FOREACH, BOOST_FOREACH] +# 对#include进行排序,匹配了某正则表达式的#include拥有对应的优先级,匹配不到的则默认优先级为INT_MAX(优先级越小排序越靠前), +# 可以定义负数优先级从而保证某些#include永远在最前面 +IncludeCategories: + - Regex: '^"(llvm|llvm-c|clang|clang-c)/' + Priority: 2 + - Regex: '^(<|"(gtest|isl|json)/)' + Priority: 3 + - Regex: ".*" + Priority: 1 +# 缩进case标签 +IndentCaseLabels: true +# 缩进宽度 +IndentWidth: 4 +# 函数返回类型换行时,缩进函数声明或函数定义的函数名 +IndentWrappedFunctionNames: true +# 保留在块开始处的空行 +KeepEmptyLinesAtTheStartOfBlocks: true +# 开始一个块的宏的正则表达式 +MacroBlockBegin: "" +# 结束一个块的宏的正则表达式 +MacroBlockEnd: "" +# 连续空行的最大数量 +MaxEmptyLinesToKeep: 1 +# 命名空间的缩进: None, Inner(缩进嵌套的命名空间中的内容), All +NamespaceIndentation: None +# 使用ObjC块时缩进宽度 +ObjCBlockIndentWidth: 4 +# 在ObjC的@property后添加一个空格 +ObjCSpaceAfterProperty: false +# 在ObjC的protocol列表前添加一个空格 +ObjCSpaceBeforeProtocolList: true +# 在call(后对函数调用换行的penalty +PenaltyBreakBeforeFirstCallParameter: 19 +# 在一个注释中引入换行的penalty +PenaltyBreakComment: 300 +# 第一次在<<前换行的penalty +PenaltyBreakFirstLessLess: 120 +# 在一个字符串字面量中引入换行的penalty +PenaltyBreakString: 1000 +# 对于每个在行字符数限制之外的字符的penalt +PenaltyExcessCharacter: 1000000 +# 将函数的返回类型放到它自己的行的penalty +PenaltyReturnTypeOnItsOwnLine: 60 +# 指针和引用的对齐: Left, Right, Middle +PointerAlignment: Left +# 允许重新排版注释 +ReflowComments: true +# 允许排序#include +SortIncludes: true +# 在C风格类型转换后添加空格 +SpaceAfterCStyleCast: false +# 在赋值运算符之前添加空格 +SpaceBeforeAssignmentOperators: true +# 开圆括号之前添加一个空格: Never, ControlStatements, Always +SpaceBeforeParens: ControlStatements +# 在空的圆括号中添加空格 +SpaceInEmptyParentheses: false +# 在尾随的评论前添加的空格数(只适用于//) +SpacesBeforeTrailingComments: 1 +# 在尖括号的<后和>前添加空格 +SpacesInAngles: false +# 在容器(ObjC和JavaScript的数组和字典等)字面量中添加空格 +SpacesInContainerLiterals: true +# 在C风格类型转换的括号中添加空格 +SpacesInCStyleCastParentheses: false +# 在圆括号的(后和)前添加空格 +SpacesInParentheses: false +# 在方括号的[后和]前添加空格,lamda表达式和未指明大小的数组的声明不受影响 +SpacesInSquareBrackets: false +# 标准: Cpp03, Cpp11, Auto +Standard: Cpp11 +# tab宽度 +TabWidth: 4 +# 使用tab字符: Never, ForIndentation, ForContinuationAndIndentation, Always +UseTab: Never diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7ff7443 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/huawei_proprietary diff --git a/BUILD.gn b/BUILD.gn new file mode 100644 index 0000000..95e0f28 --- /dev/null +++ b/BUILD.gn @@ -0,0 +1,170 @@ +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. +# 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. + +import("//build/lite/config/component/lite_component.gni") +import("//build/lite/config/subsystem/graphic/config.gni") +import("//build/lite/ndk/ndk.gni") + +lite_component("lite_ui") { + features = [ ":ui" ] + public_deps = features +} + +ndk_lib("lite_ui_ndk") { + lib_extension = ".so" + deps = [ ":ui" ] + head_files = [ "interfaces/kits" ] +} + +config("graphic_define_config") { + include_dirs = [ + "interfaces/kits", + "interfaces/innerkits", + ] + + defines = [ + "ENABLE_VECTOR_FONT=1", + "ENABLE_SHAPING=0", + "ENABLE_ICU=0", + "ENABLE_MULTI_FONT=0", + ] + + if (ohos_kernel_type == "linux") { + defines += [ "RESOURCE_DIR=\"/storage/data/\"" ] + } else { + defines += [ "RESOURCE_DIR=\"/user/data/\"" ] + } +} + +if (enable_graphic_font) { + copy("utils_config") { + sources = [ "tools/qt/simulator/font/SourceHanSansSC-Regular.otf" ] + outputs = [ "$root_out_dir/data/SourceHanSansSC-Regular.otf" ] + } +} + +shared_library("ui") { + sources = [ + "frameworks/animator/animator.cpp", + "frameworks/animator/easing_equation.cpp", + "frameworks/animator/interpolation.cpp", + "frameworks/common/graphic_startup.cpp", + "frameworks/common/image.cpp", + "frameworks/common/input_device_manager.cpp", + "frameworks/common/screen.cpp", + "frameworks/common/screen_device_proxy.cpp", + "frameworks/common/task.cpp", + "frameworks/common/text.cpp", + "frameworks/common/typed_text.cpp", + "frameworks/common/ui_font_header.cpp", + "frameworks/components/root_view.cpp", + "frameworks/components/text_adapter.cpp", + "frameworks/components/ui_abstract_clock.cpp", + "frameworks/components/ui_abstract_progress.cpp", + "frameworks/components/ui_abstract_scroll.cpp", + "frameworks/components/ui_analog_clock.cpp", + "frameworks/components/ui_arc_label.cpp", + "frameworks/components/ui_axis.cpp", + "frameworks/components/ui_box_progress.cpp", + "frameworks/components/ui_button.cpp", + "frameworks/components/ui_canvas.cpp", + "frameworks/components/ui_chart.cpp", + "frameworks/components/ui_checkbox.cpp", + "frameworks/components/ui_circle_progress.cpp", + "frameworks/components/ui_dialog.cpp", + "frameworks/components/ui_digital_clock.cpp", + "frameworks/components/ui_image_animator.cpp", + "frameworks/components/ui_image_view.cpp", + "frameworks/components/ui_label.cpp", + "frameworks/components/ui_label_button.cpp", + "frameworks/components/ui_list.cpp", + "frameworks/components/ui_picker.cpp", + "frameworks/components/ui_qrcode.cpp", + "frameworks/components/ui_radio_button.cpp", + "frameworks/components/ui_repeat_button.cpp", + "frameworks/components/ui_scroll_view.cpp", + "frameworks/components/ui_slider.cpp", + "frameworks/components/ui_surface_view.cpp", + "frameworks/components/ui_swipe_view.cpp", + "frameworks/components/ui_texture_mapper.cpp", + "frameworks/components/ui_time_picker.cpp", + "frameworks/components/ui_toggle_button.cpp", + "frameworks/components/ui_video.cpp", + "frameworks/components/ui_view.cpp", + "frameworks/components/ui_view_group.cpp", + "frameworks/core/render_manager.cpp", + "frameworks/core/task_manager.cpp", + "frameworks/default_resource/check_box_res.cpp", + "frameworks/dfx/event_injector.cpp", + "frameworks/dfx/key_event_injector.cpp", + "frameworks/dfx/point_event_injector.cpp", + "frameworks/dfx/ui_dump_dom_tree.cpp", + "frameworks/dfx/ui_screenshot.cpp", + "frameworks/dock/input_device.cpp", + "frameworks/dock/key_input_device.cpp", + "frameworks/dock/ohos/ohos_input_device.cpp", + "frameworks/dock/pointer_input_device.cpp", + "frameworks/dock/rotate_input_device.cpp", + "frameworks/dock/virtual_input_device.cpp", + "frameworks/draw/draw_arc.cpp", + "frameworks/draw/draw_curve.cpp", + "frameworks/draw/draw_image.cpp", + "frameworks/draw/draw_label.cpp", + "frameworks/draw/draw_line.cpp", + "frameworks/draw/draw_rect.cpp", + "frameworks/draw/draw_triangle.cpp", + "frameworks/draw/draw_utils.cpp", + "frameworks/events/event.cpp", + "frameworks/font/base_font.cpp", + "frameworks/font/glyphs_manager.cpp", + "frameworks/font/ui_font.cpp", + "frameworks/font/ui_font_adaptor.cpp", + "frameworks/font/ui_font_allocator.cpp", + "frameworks/font/ui_font_cache.cpp", + "frameworks/font/ui_font_vector.cpp", + "frameworks/font/ui_line_break.cpp", + "frameworks/font/ui_multi_font_manager.cpp", + "frameworks/font/ui_text_shaping.cpp", + "frameworks/imgdecode/cache_manager.cpp", + "frameworks/imgdecode/file_img_decoder.cpp", + "frameworks/imgdecode/image_load.cpp", + "frameworks/layout/flex_layout.cpp", + "frameworks/layout/grid_layout.cpp", + "frameworks/layout/list_layout.cpp", + "frameworks/themes/theme.cpp", + "frameworks/themes/theme_manager.cpp", + "frameworks/window/window.cpp", + "frameworks/window/window_impl.cpp", + ] + include_dirs = [ "//foundation/graphic/ui/frameworks" ] + deps = [ + "//build/lite/config/component/cJSON:cjson_shared", + "//foundation/graphic/surface:lite_surface", + "//foundation/graphic/utils:lite_graphic_hals", + "//foundation/graphic/wms:lite_wms", + "//foundation/multimedia/media_lite/frameworks/player_lite:player_lite", + "//third_party/bounds_checking_function:libsec_shared", + "//third_party/freetype:freetype", + "//third_party/giflib:libgif", + "//third_party/libjpeg:libjpeg", + "//third_party/libpng:libpng", + "//third_party/qrcodegen:qrcodegen", + ] + + public_deps = [ "//foundation/graphic/utils:lite_graphic_utils" ] + public_configs = [ ":graphic_define_config" ] + cflags = [ + "-Wall", + "-fno-exceptions", + ] + cflags_cc = cflags + ldflags = [ "-Wl,-rpath-link=$ohos_root_path/$root_out_dir" ] +} diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..4947287 --- /dev/null +++ b/LICENSE @@ -0,0 +1,177 @@ + + 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 \ No newline at end of file diff --git a/README.en.md b/README.en.md deleted file mode 100644 index 25d0af2..0000000 --- a/README.en.md +++ /dev/null @@ -1,36 +0,0 @@ -# graphic_ui - -#### Description -{**When you're done, you can delete the content in this README and update the file with details for others getting started with your repository**} - -#### Software Architecture -Software architecture description - -#### Installation - -1. xxxx -2. xxxx -3. xxxx - -#### Instructions - -1. xxxx -2. xxxx -3. xxxx - -#### Contribution - -1. Fork the repository -2. Create Feat_xxx branch -3. Commit your code -4. Create Pull Request - - -#### Gitee Feature - -1. You can use Readme\_XXX.md to support different languages, such as Readme\_en.md, Readme\_zh.md -2. Gitee blog [blog.gitee.com](https://blog.gitee.com) -3. Explore open source project [https://gitee.com/explore](https://gitee.com/explore) -4. The most valuable open source project [GVP](https://gitee.com/gvp) -5. The manual of Gitee [https://gitee.com/help](https://gitee.com/help) -6. The most popular members [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/) diff --git a/README.md b/README.md index 9aad453..e75dce0 100644 --- a/README.md +++ b/README.md @@ -1,39 +1,124 @@ -# graphic_ui +# UI -#### 介绍 -{**以下是 Gitee 平台说明,您可以替换此简介** -Gitee 是 OSCHINA 推出的基于 Git 的代码托管平台(同时支持 SVN)。专为开发者提供稳定、高效、安全的云端软件开发协作平台 -无论是个人、团队、或是企业,都能够用 Gitee 实现代码托管、项目管理、协作开发。企业项目请看 [https://gitee.com/enterprises](https://gitee.com/enterprises)} +- [Introduction](#section11660541593) +- [Directory Structure](#section161941989596) +- [Constraints](#section119744591305) +- [Compilation and Building](#section137768191623) +- [Description](#section1312121216216) + - [Component Description](#section66002422015) + - [Usage](#section129654513264) -#### 软件架构 -软件架构说明 +- [Repositories Involved](#section1371113476307) + +## Introduction + +The graphics UI module implements a system-level graphics engine. + +This module provides the UIKit APIs for application development. You can use the APIs to add animations, manage layouts, transform images, process events, and operates on rich UI components. + +The graphics UI directly calls the HAL API or uses the client provided by the Window Manager Service \(WMS\) to interact with the hardware to complete operations such as event response and image drawing. + +**Figure 1** Graphics subsystem architecture +![](figures/graphics-subsystem-architecture.png "graphics-subsystem-architecture") + +## Directory Structure + +``` +/foundation/graphic/ui +├── frameworks # Framework code +│ ├── animator # Animator module +│ ├── common # Common module +│ ├── components # Components +│ ├── core # UI main processes (such as rendering and task management) +│ ├── default_resource +│ ├── dfx # Maintenance and test +│ ├── dock # Driver adaptation layer +│ │ └── ohos # OHOS platform adaptation +│ ├── draw # Drawing logic +│ ├── engines # Drawing engines +│ │ ├── dfb +│ │ ├── general +│ │ ├── gpu_vglite +│ │ └── software_zlite +│ ├── events # Events +│ ├── font # Fonts +│ ├── imgdecode # Image management +│ ├── layout # Page layout +│ ├── themes # Theme management +│ ├── window # Window management adaptation layer +│ └── window_manager +│ └── dfb +├── interfaces # APIs +│ ├── innerkits # APIs between modules +│ │ └── xxx # Sub-module APIs +│ └── kits # Externel APIs +│ │ └── xxx # Sub-module APIs +├── test # Test code +│ ├── framework +│ │ ├── include # Header files for the test framework +│ │ └── src # Source code for the test framework +│ ├── uitest # Display effect test (The executable program is in foundation/graphic/wms/test:sample_ui.) +│ │ └── test_xxx # Specific UI effect test +│ └── unittest # Unit testing +│ └── xxx # Unit testing for a specific UI component +└── tools # Test and simulation tools (simulator projects and resource files) + └── qt # Qt project +``` + +## Constraints + +Platform Constraints + +- The Windows platform supports only Qt and OHOS IDE. +- For the support of other platforms, see the **graphic** tag in **vender/hisilicon/\[product\_name\]/config.json**. If the **graphic** tag does not exist, it indicates that the product does not have the graphics subsystem. + +## Compilation and Building + +``` +# Generate the libui.so file in the out directory of the product folder through GN compilation. +hb build lite_ui + +# To compile the Qt library, see the Qt simulator project at graphic/ui/tools/qt/simulator/simulator.pro. +``` + +## Description + +### Component Description + +Components are classified into basic components and container components. + +- Basic components: Implement only a single function, such as **Text**, **Button**, **Image**, and **List**. +- Container components: Hold and combine child components to implement complex functions. + +**Figure 2** Graphics subsystem components +![](figures/graphics-subsystem-components.png "graphics-subsystem-components") + +### Usage + +For details about how to use components and APIs of graphics, see the examples provided in **foundation/graphic/ui/test/uitest**. + +- The Qt project can be debugged in the Windows environment. + + Project file path: + + ``` + graphic/ui/tools/qt/simulator/simulator.pro + ``` + +- For other debugging environments, you can run **foundation/graphic/wms/test:sample\_ui**. + + ``` + hb build lite_wms -b debug + ``` + + After the building is successful, the executable program **out/\[product\_name\]/dev\_tools/bin/sample\_ui** is obtained. You can run the program in an environment to view the display effect of a specific component. -#### 安装教程 +## Repositories Involved -1. xxxx -2. xxxx -3. xxxx +/hmf/graphic/surface -#### 使用说明 +/hmf/graphic/wms -1. xxxx -2. xxxx -3. xxxx +/hmf/graphic/utils -#### 参与贡献 - -1. Fork 本仓库 -2. 新建 Feat_xxx 分支 -3. 提交代码 -4. 新建 Pull Request - - -#### 特技 - -1. 使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md -2. Gitee 官方博客 [blog.gitee.com](https://blog.gitee.com) -3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解 Gitee 上的优秀开源项目 -4. [GVP](https://gitee.com/gvp) 全称是 Gitee 最有价值开源项目,是综合评定出的优秀开源项目 -5. Gitee 官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help) -6. Gitee 封面人物是一档用来展示 Gitee 会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/) diff --git a/README_zh.md b/README_zh.md new file mode 100644 index 0000000..621bf8a --- /dev/null +++ b/README_zh.md @@ -0,0 +1,124 @@ +# 图形UI组件 + +- [简介](#section11660541593) +- [目录](#section161941989596) +- [约束](#section119744591305) +- [编译构建](#section137768191623) +- [说明](#section1312121216216) + - [组件说明](#section66002422015) + - [使用说明](#section129654513264) + +- [相关仓](#section1371113476307) + +## 简介 + +图形UI组件实现了一套系统级的图形引擎。 + +该组件为应用开发提供UIKit接口,包括了动画、布局、图形转换、事件处理,以及丰富的UI组件。 + +组件内部直接调用HAL接口,或者使用WMS\(Window Manager Service\)提供的客户端与硬件交互,以完成事件响应、图像绘制等操作。 + +**图 1** 图形子系统架构图 +![](figures/图形子系统架构图.png "图形子系统架构图") + +## 目录 + +``` +/foundation/graphic/ui +├── frameworks # 框架代码 +│ ├── animator # 动画模块 +│ ├── common # 公共模块 +│ ├── components # 组件 +│ ├── core # ui主流程(渲染、任务管理等) +│ ├── default_resource +│ ├── dfx # 维测功能 +│ ├── dock # 驱动适配层 +│ │ └── ohos # ohos平台适配 +│ ├── draw # 绘制逻辑 +│ ├── engines # 绘制引擎 +│ │ ├── dfb +│ │ ├── general +│ │ ├── gpu_vglite +│ │ └── software_zlite +│ ├── events # 事件 +│ ├── font # 字体 +│ ├── imgdecode # 图片管理 +│ ├── layout # 页面布局 +│ ├── themes # 主题管理 +│ ├── window # 窗口管理适配层 +│ └── window_manager +│ └── dfb +├── interfaces # 接口 +│ ├── innerkits # 模块间接口 +│ │ └── xxx # 子模块的接口 +│ └── kits # 对外接口 +│ └── xxx # 子模块的接口 +├── test # 测试代码 +│ ├── framework +│ │ ├── include # 测试框架头文件 +│ │ └── src # 测试框架源码 +│ ├── uitest # 显示效果测试(可执行程序在foundation/graphic/wms/test:sample_ui) +│ │ └── test_xxx # 具体UI组件效果测试 +│ └── unittest # 单元测试 +│ └── xxx # 具体UI组件单元测试 +└── tools # 测试和模拟器工具(模拟器工程、资源文件) + └── qt # QT工程 +``` + +## 约束 + +平台约束 + +- Windows平台仅支持QT和OHOS IDE。 +- 其他平台支持情况参考vender/hisilicon/\[product\_name\]/config.json中的graphic标签(不存在graphic标签即该产品不存在图形子系统)。 + +## 编译构建 + +``` +# 通过gn编译,在out目录下对应产品的文件夹中生成libui.so +hb build lite_ui + +# 编译qt库可直接参考qt模拟器工程:graphic/ui/tools/qt/simulator/simulator.pro +``` + +## 说明 + +### 组件说明 + +组件分为基础组件和容器组件 + +- 基础组件:仅实现组件自身单一功能,比如按钮、文字、图片等; +- 容器组件:可将其他组件作为自己的子组件,通过组合实现复杂功能。 + +**图 2** 图形组件一览 +![](figures/图形组件一览.png "图形组件一览") + +### 使用说明 + +foundation/graphic/ui/test/uitest中提供了图形所有组件和功能接口的使用范例。 + +- Windows环境可运行QT工程调试 + + 工程文件路径: + + ``` + graphic/ui/tools/qt/simulator/simulator.pro + ``` + +- 其他调试环境可以编译运行foundation/graphic/wms/test:sample\_ui + + ``` + hb build lite_wms -b debug + ``` + + 编译成功后得到可执行程序out/\[product\_name\]/dev\_tools/bin/sample\_ui,在实际环境上运行即可观察对应组件显示效果。 + + +## 相关仓 + +/hmf/graphic/surface + +/hmf/graphic/wms + +/hmf/graphic/utils + diff --git a/figures/graphics-subsystem-architecture.png b/figures/graphics-subsystem-architecture.png new file mode 100644 index 0000000..b848d79 Binary files /dev/null and b/figures/graphics-subsystem-architecture.png differ diff --git a/figures/graphics-subsystem-components.png b/figures/graphics-subsystem-components.png new file mode 100644 index 0000000..123e1d9 Binary files /dev/null and b/figures/graphics-subsystem-components.png differ diff --git a/figures/图形子系统架构图.png b/figures/图形子系统架构图.png new file mode 100644 index 0000000..b848d79 Binary files /dev/null and b/figures/图形子系统架构图.png differ diff --git a/figures/图形组件一览.png b/figures/图形组件一览.png new file mode 100644 index 0000000..123e1d9 Binary files /dev/null and b/figures/图形组件一览.png differ diff --git a/frameworks/animator/animator.cpp b/frameworks/animator/animator.cpp new file mode 100755 index 0000000..0629cbe --- /dev/null +++ b/frameworks/animator/animator.cpp @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "animator/animator.h" + +#include "common/task_manager.h" +#include "hal_tick.h" + +namespace OHOS { +void Animator::Start() +{ + SetState(START); + runTime_ = 0; + lastRunTime_ = 0; +} + +void Animator::Stop() +{ + SetState(STOP); + if (callback_ != nullptr) { + callback_->OnStop(*view_); + } +} + +void Animator::Pause() +{ + SetState(PAUSE); +} + +void Animator::Resume() +{ + SetState(START); + lastRunTime_ = HALTick::GetInstance().GetTime(); +} + +void Animator::Run() +{ + if (lastRunTime_ == 0) { + lastRunTime_ = HALTick::GetInstance().GetTime(); + } + + uint32_t elepse = HALTick::GetInstance().GetElapseTime(lastRunTime_); + + runTime_ = (UINT32_MAX - elepse > runTime_) ? (runTime_ + elepse) : time_; + lastRunTime_ = HALTick::GetInstance().GetTime(); + if (callback_ != nullptr) { + callback_->Callback(view_); + } +} + +void AnimatorManager::Init() +{ + Task::Init(); +} + +void AnimatorManager::Add(Animator* animator) +{ + if (animator == nullptr) { + return; + } + + list_.PushBack(animator); +} + +void AnimatorManager::Remove(const Animator* animator) +{ + if (animator == nullptr) { + return; + } + ListNode* pos = list_.Begin(); + while (pos != list_.End()) { + if (pos->data_ == animator) { + list_.Remove(pos); + return; + } + pos = pos->next_; + } +} + +void AnimatorManager::AnimatorTask() +{ + ListNode* pos = list_.Begin(); + Animator* animator = nullptr; + + while (pos != list_.End()) { + animator = pos->data_; + if (animator->GetState() == Animator::START) { + if (animator->IsRepeat() || (animator->GetRunTime() <= animator->GetTime())) { + animator->Run(); + } else { + animator->Stop(); + } + } + + pos = pos->next_; + } +} +} diff --git a/frameworks/animator/easing_equation.cpp b/frameworks/animator/easing_equation.cpp new file mode 100755 index 0000000..9d46fb0 --- /dev/null +++ b/frameworks/animator/easing_equation.cpp @@ -0,0 +1,254 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "animator/easing_equation.h" +#include "graphic_math.h" + +namespace OHOS { +double EasingEquation::overshoot_ = 1.7; // The empirical value commonly used in easing equation + +void EasingEquation::SetBackOvershoot(double overshoot) +{ + if ((overshoot >= OVERSHOOT_MIN) && (overshoot <= OVERSHOOT_MAX)) { + overshoot_ = overshoot; + } +} + +int16_t EasingEquation::BackEaseIn(int16_t startPos, int16_t endPos, uint16_t curTime, uint16_t durationTime) +{ + if (curTime < durationTime) { + double t = -(static_cast(curTime) / durationTime); + double x = -t * t * ((overshoot_ + 1) * t + overshoot_); + return static_cast((x * (static_cast(endPos) - startPos)) + startPos); + } + + return endPos; +} + +int16_t EasingEquation::BackEaseOut(int16_t startPos, int16_t endPos, uint16_t curTime, uint16_t durationTime) +{ + if (curTime < durationTime) { + double t = static_cast(curTime) / durationTime; + t -= 1.0; + double x = t * t * ((overshoot_ + 1) * t + overshoot_) + 1; + return static_cast((x * (static_cast(endPos) - startPos)) + startPos); + } + + return endPos; +} + +int16_t EasingEquation::BackEaseInOut(int16_t startPos, int16_t endPos, uint16_t curTime, uint16_t durationTime) +{ + uint16_t halfTime = durationTime >> 1; + int16_t halfStep = (endPos >> 1) + (startPos >> 1); + if (curTime < halfTime) { + return BackEaseIn(startPos, halfStep, curTime, halfTime); + } + return BackEaseOut(halfStep, endPos, curTime - halfTime, halfTime); +} + +/* 1 - sqrt(1 - t^2) */ +int16_t EasingEquation::CircEaseIn(int16_t startPos, int16_t endPos, uint16_t curTime, uint16_t durationTime) +{ + if (curTime < durationTime) { + int32_t t = (curTime << INTERPOLATION_RANGE_OFFSET) / durationTime; + uint32_t x = INTERPOLATION_RANGE - Sqrt(INTERPOLATION_RANGE_SQUARE - t * t); + return static_cast(((x * (static_cast(endPos) - startPos)) >> INTERPOLATION_RANGE_OFFSET) + + startPos); + } + + return endPos; +} + +/* sqrt(1 - (1 - t)^2) */ +int16_t EasingEquation::CircEaseOut(int16_t startPos, int16_t endPos, uint16_t curTime, uint16_t durationTime) +{ + if (curTime < durationTime) { + int32_t t = INTERPOLATION_RANGE - (curTime << INTERPOLATION_RANGE_OFFSET) / durationTime; + uint32_t x = static_cast(Sqrt(INTERPOLATION_RANGE_SQUARE - t * t)); + return static_cast(((x * (static_cast(endPos) - startPos)) >> INTERPOLATION_RANGE_OFFSET) + + startPos); + } + + return endPos; +} + +int16_t EasingEquation::CircEaseInOut(int16_t startPos, int16_t endPos, uint16_t curTime, uint16_t durationTime) +{ + uint16_t halfTime = durationTime >> 1; + int16_t halfStep = (endPos >> 1) + (startPos >> 1); + if (curTime < halfTime) { + return CircEaseIn(startPos, halfStep, curTime, halfTime); + } + return CircEaseOut(halfStep, endPos, curTime - halfTime, halfTime); +} + +/* t^3 */ +int16_t EasingEquation::CubicEaseIn(int16_t startPos, int16_t endPos, uint16_t curTime, uint16_t durationTime) +{ + if (curTime < durationTime) { + int32_t t = (curTime << INTERPOLATION_RANGE_OFFSET) / durationTime; + int16_t x = (t * t * t) >> (INTERPOLATION_RANGE_OFFSET << 1); + return static_cast(((x * (static_cast(endPos) - startPos)) >> INTERPOLATION_RANGE_OFFSET) + + startPos); + } + + return endPos; +} + +/* 1 - (1 - t)^3 */ +int16_t EasingEquation::CubicEaseOut(int16_t startPos, int16_t endPos, uint16_t curTime, uint16_t durationTime) +{ + if (curTime < durationTime) { + int32_t t = (curTime << INTERPOLATION_RANGE_OFFSET) / durationTime; + t = INTERPOLATION_RANGE - t; + int16_t x = INTERPOLATION_RANGE - ((t * t * t) >> (INTERPOLATION_RANGE_OFFSET << 1)); + return static_cast(((x * (static_cast(endPos) - startPos)) >> INTERPOLATION_RANGE_OFFSET) + + startPos); + } + + return endPos; +} + +int16_t EasingEquation::CubicEaseInOut(int16_t startPos, int16_t endPos, uint16_t curTime, uint16_t durationTime) +{ + uint16_t halfTime = durationTime >> 1; + int16_t halfStep = (endPos >> 1) + (startPos >> 1); + if (curTime < halfTime) { + return CubicEaseIn(startPos, halfStep, curTime, halfTime); + } + return CubicEaseOut(halfStep, endPos, curTime - halfTime, halfTime); +} + +int16_t EasingEquation::LinearEaseNone(int16_t startPos, int16_t endPos, uint16_t curTime, uint16_t durationTime) +{ + if (curTime < durationTime) { + int32_t t = (curTime << INTERPOLATION_RANGE_OFFSET) / durationTime; + return static_cast(((t * (static_cast(endPos) - startPos)) >> INTERPOLATION_RANGE_OFFSET) + + startPos); + } + + return endPos; +} + +/* t^2 */ +int16_t EasingEquation::QuadEaseIn(int16_t startPos, int16_t endPos, uint16_t curTime, uint16_t durationTime) +{ + if (curTime < durationTime) { + int32_t t = (curTime << INTERPOLATION_RANGE_OFFSET) / durationTime; + int16_t x = (t * t) >> INTERPOLATION_RANGE_OFFSET; + return static_cast(((x * (static_cast(endPos) - startPos)) >> INTERPOLATION_RANGE_OFFSET) + + startPos); + } + + return endPos; +} + +/* 1 - (1 - t)^2 */ +int16_t EasingEquation::QuadEaseOut(int16_t startPos, int16_t endPos, uint16_t curTime, uint16_t durationTime) +{ + if (curTime < durationTime) { + int32_t t = INTERPOLATION_RANGE - (curTime << INTERPOLATION_RANGE_OFFSET) / durationTime; + int16_t x = INTERPOLATION_RANGE - ((t * t) >> INTERPOLATION_RANGE_OFFSET); + return static_cast(((x * (static_cast(endPos) - startPos)) >> INTERPOLATION_RANGE_OFFSET) + + startPos); + } + + return endPos; +} + +int16_t EasingEquation::QuadEaseInOut(int16_t startPos, int16_t endPos, uint16_t curTime, uint16_t durationTime) +{ + uint16_t halfTime = durationTime >> 1; + int16_t halfStep = (endPos >> 1) + (startPos >> 1); + if (curTime < halfTime) { + return QuadEaseIn(startPos, halfStep, curTime, halfTime); + } + return QuadEaseOut(halfStep, endPos, curTime - halfTime, halfTime); +} + +/* t^5 */ +int16_t EasingEquation::QuintEaseIn(int16_t startPos, int16_t endPos, uint16_t curTime, uint16_t durationTime) +{ + if (curTime < durationTime) { + int64_t t = (curTime << INTERPOLATION_RANGE_OFFSET) / durationTime; + + /* 4: the fourth power of t */ + int16_t x = (t * t * t * t * t) >> (INTERPOLATION_RANGE_OFFSET * 4); + return static_cast(((x * (static_cast(endPos) - startPos)) >> INTERPOLATION_RANGE_OFFSET) + + startPos); + } + + return endPos; +} + +/* 1 - (1 - t)^5 */ +int16_t EasingEquation::QuintEaseOut(int16_t startPos, int16_t endPos, uint16_t curTime, uint16_t durationTime) +{ + if (curTime < durationTime) { + int64_t t = (curTime << INTERPOLATION_RANGE_OFFSET) / durationTime; + t = INTERPOLATION_RANGE - t; + + /* 4: the fourth power of t */ + int16_t x = INTERPOLATION_RANGE - ((t * t * t * t * t) >> (INTERPOLATION_RANGE_OFFSET * 4)); + return static_cast(((x * (static_cast(endPos) - startPos)) >> INTERPOLATION_RANGE_OFFSET) + + startPos); + } + + return endPos; +} + +int16_t EasingEquation::QuintEaseInOut(int16_t startPos, int16_t endPos, uint16_t curTime, uint16_t durationTime) +{ + uint16_t halfTime = durationTime >> 1; + int16_t halfStep = (endPos >> 1) + (startPos >> 1); + if (curTime < halfTime) { + return QuintEaseIn(startPos, halfStep, curTime, halfTime); + } + return QuintEaseOut(halfStep, endPos, curTime - halfTime, halfTime); +} + +int16_t EasingEquation::SineEaseIn(int16_t startPos, int16_t endPos, uint16_t curTime, uint16_t durationTime) +{ + if (curTime < durationTime) { + int16_t t = (curTime * QUARTER_IN_DEGREE) / durationTime - QUARTER_IN_DEGREE; + float x = Sin(t) + 1; + return static_cast(x * (endPos - startPos)) + startPos; + } + + return endPos; +} + +int16_t EasingEquation::SineEaseOut(int16_t startPos, int16_t endPos, uint16_t curTime, uint16_t durationTime) +{ + if (curTime < durationTime) { + int16_t t = (curTime * QUARTER_IN_DEGREE) / durationTime; + float x = Sin(t); + return static_cast(x * (endPos - startPos)) + startPos; + } + + return endPos; +} + +int16_t EasingEquation::SineEaseInOut(int16_t startPos, int16_t endPos, uint16_t curTime, uint16_t durationTime) +{ + uint16_t halfTime = durationTime >> 1; + int16_t halfStep = (endPos >> 1) + (startPos >> 1); + if (curTime < halfTime) { + return SineEaseIn(startPos, halfStep, curTime, halfTime); + } + return SineEaseOut(halfStep, endPos, curTime - halfTime, halfTime); +} +} \ No newline at end of file diff --git a/frameworks/animator/interpolation.cpp b/frameworks/animator/interpolation.cpp new file mode 100755 index 0000000..02c8471 --- /dev/null +++ b/frameworks/animator/interpolation.cpp @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "animator/interpolation.h" + +namespace OHOS { +/* B(t) = P0*(1-t)^3 + 3*P1*t*(1-t)^2 + 3*P2*t^2*(1-t) + P3*t^3 */ +int16_t Interpolation::GetBezierInterpolation(int16_t t, int16_t u0, int16_t u1, int16_t u2, int16_t u3) +{ + int64_t invT = INTERPOLATION_RANGE - t; + int64_t invT2 = invT * invT; + int64_t invT3 = invT2 * invT; + int64_t t2 = t * t; + int64_t t3 = t2 * t; + + int64_t ret = invT3 * u0; + ret += BESSEL_COEFFICIENT * invT2 * t * u1; + ret += BESSEL_COEFFICIENT * invT * t2 * u2; + ret += t3 * u3; + ret = ret >> CUBIC_BEZIER_CALCULATE_OFFSET; + return static_cast(ret); +} +} diff --git a/frameworks/common/graphic_startup.cpp b/frameworks/common/graphic_startup.cpp new file mode 100644 index 0000000..5e42e99 --- /dev/null +++ b/frameworks/common/graphic_startup.cpp @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "common/graphic_startup.h" +#include "animator/animator.h" +#include "common/input_device_manager.h" +#include "common/task_manager.h" +#include "core/render_manager.h" +#include "dfx/performance_task.h" +#include "file.h" +#include "font/ui_font.h" +#if ENABLE_SHAPING +#include "font/ui_text_shaping.h" +#endif +#include "graphic_log.h" +#include "imgdecode/cache_manager.h" +#ifdef VERSION_STANDARD +#include "dock/ohos/ohos_input_device.h" +#endif +#if ENABLE_WINDOW +#include "iwindows_manager.h" +#endif +#if ENABLE_GFX_ENGINES +#include "hals/gfx_engines.h" +#endif + +namespace OHOS { +void GraphicStartUp::InitFontEngine(uintptr_t psramAddr, uint32_t psramLen, const char* dPath, const char* ttfName) +{ +#if ENABLE_VECTOR_FONT + UIFont* fontEngine = UIFont::GetInstance(); + if (fontEngine == nullptr) { + GRAPHIC_LOGE("Get UIFont error"); + return; + } + fontEngine->SetPsramMemory(psramAddr, psramLen); + // font and glyph path + int8_t ret = fontEngine->SetFontPath(const_cast(dPath), nullptr); + if (ret == INVALID_RET_VALUE) { + GRAPHIC_LOGW("SetFontPath failed"); + } + if (ttfName != nullptr) { + uint8_t ret2 = fontEngine->RegisterFontInfo(ttfName); + if (ret2 == INVALID_UCHAR_ID) { + GRAPHIC_LOGW("SetTtfName failed"); + } + } +#endif +} + +void GraphicStartUp::Init() +{ + TaskManager::GetInstance()->SetTaskRun(true); + DEBUG_PERFORMANCE_TASK_INIT(); + + if (INDEV_READ_PERIOD > 0) { + InputDeviceManager::GetInstance()->Init(); + } + AnimatorManager::GetInstance()->Init(); + + StyleDefault::Init(); + RenderManager::GetInstance().Init(); + + CacheManager::GetInstance().Init(IMG_CACHE_SIZE); +#ifdef VERSION_STANDARD + OHOSInputDevice* input = new OHOSInputDevice(); + if (input == nullptr) { + GRAPHIC_LOGE("new OHOSInputDevice fail"); + return; + } + InputDeviceManager::GetInstance()->Add(input); +#endif + +#if ENABLE_WINDOW + IWindowsManager::GetInstance()->Init(); +#endif +#if ENABLE_GFX_ENGINES + GfxEngines::GetInstance()->InitDriver(); +#endif +} +} // namespace OHOS diff --git a/frameworks/common/image.cpp b/frameworks/common/image.cpp new file mode 100755 index 0000000..e58af8c --- /dev/null +++ b/frameworks/common/image.cpp @@ -0,0 +1,449 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "common/image.h" +#include "common/image_decode_ability.h" +#include "draw/draw_image.h" +#include "file.h" +#include "graphic_log.h" +#include "imgdecode/cache_manager.h" +#if ENABLE_JPEG_AND_PNG +#include "jpeglib.h" +#include "png.h" +#endif +#include "securec.h" + +namespace OHOS { +Image::Image() : imageInfo_(nullptr), path_(nullptr), srcType_(IMG_SRC_UNKNOWN), mallocFlag_(false) {} + +Image::~Image() +{ + if (srcType_ == IMG_SRC_FILE) { + CacheManager::GetInstance().Close(path_); + } + if (imageInfo_ != nullptr) { + if (mallocFlag_) { + if (imageInfo_->data != nullptr) { + UIFree(reinterpret_cast(const_cast(imageInfo_->data))); + } + mallocFlag_ = false; + } + UIFree(reinterpret_cast(const_cast(imageInfo_))); + imageInfo_ = nullptr; + } + if (path_ != nullptr) { + UIFree(reinterpret_cast(const_cast(path_))); + path_ = nullptr; + } + srcType_ = IMG_SRC_UNKNOWN; +} + +void Image::GetHeader(ImageHeader& header) const +{ + if ((srcType_ == IMG_SRC_VARIABLE) && (imageInfo_ != nullptr)) { + header = imageInfo_->header; + } else if ((srcType_ == IMG_SRC_FILE) && (path_ != nullptr)) { + CacheManager::GetInstance().GetImageHeader(path_, header); + } +} + +#if ENABLE_JPEG_AND_PNG +Image::ImageType Image::CheckImgType(const char* src) +{ + char buf[IMG_BYTES_TO_CHECK] = {0}; +#ifdef _WIN32 + int32_t fd = open(src, O_RDONLY | O_BINARY); +#else + int32_t fd = open(src, O_RDONLY); +#endif + if (fd < 0) { + GRAPHIC_LOGE("can't open %s\n", src); + return IMG_UNKNOWN; + } + if (read(fd, buf, IMG_BYTES_TO_CHECK) != IMG_BYTES_TO_CHECK) { + close(fd); + return IMG_UNKNOWN; + } + close(fd); + if (!png_sig_cmp(reinterpret_cast(buf), 0, IMG_BYTES_TO_CHECK)) { + return IMG_PNG; + // 0xFF 0xD8: JPEG file's header + } else if ((static_cast(buf[0]) == 0xFF) && (static_cast(buf[1]) == 0xD8)) { + return IMG_JPEG; + } + return IMG_UNKNOWN; +} +#endif + +bool Image::SetStandardSrc(const char* src) +{ + if (src == nullptr) { + return false; + } + const char* ptr = strrchr(src, '.'); + if (ptr == nullptr) { + srcType_ = IMG_SRC_UNKNOWN; + return false; + } + +#if ENABLE_JPEG_AND_PNG + ImageType imageType = CheckImgType(src); + if (imageType == IMG_PNG) { + return SetPNGSrc(src); + } else if (imageType == IMG_JPEG) { + return SetJPEGSrc(src); + } +#endif + + size_t strLen = strlen(src) + 1; + char* imagePath = static_cast(UIMalloc(static_cast(strLen))); + if (imagePath == nullptr) { + srcType_ = IMG_SRC_UNKNOWN; + return false; + } + + if (strcpy_s(imagePath, strLen, src) != EOK) { + UIFree(reinterpret_cast(imagePath)); + imagePath = nullptr; + srcType_ = IMG_SRC_UNKNOWN; + return false; + } + path_ = imagePath; + srcType_ = IMG_SRC_FILE; + return true; +} + +bool Image::SetLiteSrc(const char* src) +{ + if (src == nullptr) { + return false; + } + const char* ptr = strrchr(src, '.'); + if (ptr == nullptr) { + srcType_ = IMG_SRC_UNKNOWN; + return false; + } + + size_t strLen = strlen(src) + 1; + char* imagePath = static_cast(UIMalloc(static_cast(strLen))); + if (imagePath == nullptr) { + srcType_ = IMG_SRC_UNKNOWN; + return false; + } + if (IsImgValid(ptr)) { + const char* suffixName = "bin"; + if (memcpy_s(imagePath, strLen, src, strLen) != EOK) { + UIFree(reinterpret_cast(imagePath)); + imagePath = nullptr; + srcType_ = IMG_SRC_UNKNOWN; + return false; + } + (ptr - src + imagePath)[1] = '\0'; // remove suffix + if (strcat_s(imagePath, strLen, suffixName) != EOK) { + UIFree(reinterpret_cast(imagePath)); + imagePath = nullptr; + srcType_ = IMG_SRC_UNKNOWN; + return false; + } + } else { + if (memcpy_s(imagePath, strLen, src, strLen) != EOK) { + UIFree(reinterpret_cast(imagePath)); + imagePath = nullptr; + srcType_ = IMG_SRC_UNKNOWN; + return false; + } + } + path_ = imagePath; + srcType_ = IMG_SRC_FILE; + return true; +} + +bool Image::SetSrc(const char* src) +{ + if (path_ != nullptr) { + UIFree(reinterpret_cast(const_cast(path_))); + path_ = nullptr; + } + + if (src != nullptr) { + uint32_t imageType = ImageDecodeAbility::GetInstance().GetImageDecodeAbility(); + if (((imageType & IMG_SUPPORT_JPEG) == IMG_SUPPORT_JPEG) || + ((imageType & IMG_SUPPORT_PNG) == IMG_SUPPORT_PNG)) { + return SetStandardSrc(src); + } + return SetLiteSrc(src); + } else { + path_ = src; + srcType_ = IMG_SRC_UNKNOWN; + } + return true; +} + +bool Image::SetSrc(const ImageInfo* src) +{ + if (imageInfo_ != nullptr) { + if (mallocFlag_) { + if (imageInfo_->data != nullptr) { + UIFree(reinterpret_cast(const_cast(imageInfo_->data))); + } + mallocFlag_ = false; + } + UIFree(reinterpret_cast(const_cast(imageInfo_))); + imageInfo_ = nullptr; + } + + if (src != nullptr) { + imageInfo_ = static_cast(UIMalloc(static_cast(sizeof(ImageInfo)))); + if (imageInfo_ == nullptr) { + srcType_ = IMG_SRC_UNKNOWN; + return false; + } + + if (memcpy_s(const_cast(imageInfo_), sizeof(ImageInfo), src, sizeof(ImageInfo)) != EOK) { + srcType_ = IMG_SRC_UNKNOWN; + return false; + } + + srcType_ = IMG_SRC_VARIABLE; + } else { + imageInfo_ = src; + srcType_ = IMG_SRC_UNKNOWN; + } + return true; +} + +void Image::DrawImage(const Rect& coords, const Rect& mask, const Style& style, uint8_t opaScale) const +{ + if (srcType_ == IMG_SRC_VARIABLE) { + DrawImage::DrawCommon(coords, mask, imageInfo_, style, opaScale); + } else if (srcType_ == IMG_SRC_FILE) { + DrawImage::DrawCommon(coords, mask, path_, style, opaScale); + } else { + GRAPHIC_LOGE("Image::DrawImage:: failed with error srctype!\n"); + } +} + +#if ENABLE_JPEG_AND_PNG +bool Image::SetPNGSrc(const char* src) +{ + FILE* infile = nullptr; + png_bytep* rowPointer = nullptr; + png_structp png = png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr); + if (png == nullptr) { + srcType_ = IMG_SRC_UNKNOWN; + return false; + } + png_infop info = png_create_info_struct(png); + if (info == nullptr) { + srcType_ = IMG_SRC_UNKNOWN; + png_destroy_read_struct(&png, &info, nullptr); + return false; + } + if ((infile = fopen(src, "rb")) == nullptr) { + GRAPHIC_LOGE("can't open %s\n", src); + srcType_ = IMG_SRC_UNKNOWN; + png_destroy_read_struct(&png, &info, nullptr); + return false; + } + png_init_io(png, infile); + png_read_info(png, info); + + uint8_t pixelByteSize = DrawUtils::GetPxSizeByColorMode(ARGB8888) >> 3; // 3: Shift right 3 bits + uint16_t width = png_get_image_width(png, info); + uint16_t height = png_get_image_height(png, info); + uint8_t colorType = png_get_color_type(png, info); + uint8_t bitDepth = png_get_bit_depth(png, info); + uint32_t dataSize = height * width * pixelByteSize; + + if ((colorType == PNG_COLOR_TYPE_GRAY) && (bitDepth < 8)) { // 8: Expand grayscale images to the full 8 bits + png_set_expand_gray_1_2_4_to_8(png); + } + if ((colorType == PNG_COLOR_TYPE_GRAY) || (colorType == PNG_COLOR_TYPE_GRAY_ALPHA)) { + png_set_gray_to_rgb(png); + } + if (colorType == PNG_COLOR_TYPE_PALETTE) { + png_set_palette_to_rgb(png); + } + if (bitDepth == 16) { // 16: Chop 16-bit depth images to 8-bit depth + png_set_strip_16(png); + } + if (png_get_valid(png, info, PNG_INFO_tRNS)) { + png_set_tRNS_to_alpha(png); + } + if (!(colorType & PNG_COLOR_MASK_ALPHA)) { + png_set_add_alpha(png, 0xFF, PNG_FILLER_AFTER); + } + png_set_interlace_handling(png); + png_read_update_info(png, info); + + rowPointer = static_cast(UIMalloc(sizeof(png_bytep) * height)); + if (rowPointer == nullptr) { + srcType_ = IMG_SRC_UNKNOWN; + fclose(infile); + png_destroy_read_struct(&png, &info, nullptr); + return false; + } + for (uint16_t y = 0; y < height; y++) { + rowPointer[y] = static_cast(UIMalloc(png_get_rowbytes(png, info))); + if (rowPointer[y] == nullptr) { + for (uint16_t i = 0; i < y; i++) { + UIFree(rowPointer[i]); + rowPointer[i] = nullptr; + } + fclose(infile); + UIFree(rowPointer); + srcType_ = IMG_SRC_UNKNOWN; + png_destroy_read_struct(&png, &info, nullptr); + return false; + } + } + png_read_image(png, rowPointer); + fclose(infile); + png_destroy_read_struct(&png, &info, nullptr); + ImageInfo* imgInfo = static_cast(UIMalloc(sizeof(ImageInfo))); + if (imgInfo == nullptr) { + for (uint16_t i = 0; i < height; i++) { + UIFree(rowPointer[i]); + rowPointer[i] = nullptr; + } + UIFree(rowPointer); + srcType_ = IMG_SRC_UNKNOWN; + return false; + } + uint8_t* srcData = static_cast(UIMalloc(dataSize)); + if (srcData == nullptr) { + for (uint16_t i = 0; i < height; i++) { + UIFree(rowPointer[i]); + rowPointer[i] = nullptr; + } + UIFree(rowPointer); + UIFree(imgInfo); + srcType_ = IMG_SRC_UNKNOWN; + return false; + } + uint32_t n = 0; + for (uint16_t y = 0; y < height; y++) { + png_bytep row = rowPointer[y]; + for (uint16_t x = 0; x < width * pixelByteSize; x += pixelByteSize) { + srcData[n++] = row[x + 2]; // 2: B channel + srcData[n++] = row[x + 1]; // 1: G channel + srcData[n++] = row[x + 0]; // 0: R channel + srcData[n++] = row[x + 3]; // 3: Alpha channel + } + UIFree(row); + row = nullptr; + } + UIFree(rowPointer); + + imgInfo->header.width = width; + imgInfo->header.height = height; + imgInfo->header.colorMode = ARGB8888; + imgInfo->dataSize = dataSize; + imgInfo->data = srcData; + + if (imageInfo_ != nullptr) { + if (mallocFlag_) { + if (imageInfo_->data != nullptr) { + UIFree(reinterpret_cast(const_cast(imageInfo_->data))); + } + mallocFlag_ = false; + } + UIFree(reinterpret_cast(const_cast(imageInfo_))); + imageInfo_ = nullptr; + } + imageInfo_ = imgInfo; + mallocFlag_ = true; + srcType_ = IMG_SRC_VARIABLE; + return true; +} + +bool Image::SetJPEGSrc(const char* src) +{ + struct jpeg_decompress_struct cinfo; + struct jpeg_error_mgr jerr; + FILE* infile = nullptr; + + if ((infile = fopen(src, "rb")) == nullptr) { + GRAPHIC_LOGE("can't open %s\n", src); + srcType_ = IMG_SRC_UNKNOWN; + return false; + } + cinfo.err = jpeg_std_error(&jerr); + jpeg_create_decompress(&cinfo); + jpeg_stdio_src(&cinfo, infile); + jpeg_read_header(&cinfo, TRUE); + jpeg_start_decompress(&cinfo); + + uint8_t pixelByteSize = DrawUtils::GetPxSizeByColorMode(ARGB8888) >> 3; // 3: Shift right 3 bits + uint16_t width = cinfo.output_width; + uint16_t height = cinfo.output_height; + uint32_t dataSize = width * height * pixelByteSize; + uint16_t rowStride = cinfo.output_width * pixelByteSize; + JSAMPARRAY buffer = (*cinfo.mem->alloc_sarray)(reinterpret_cast(&cinfo), JPOOL_IMAGE, rowStride, + 1); // 1: one-row-high array + ImageInfo* imgInfo = static_cast(UIMalloc(sizeof(ImageInfo))); + if (imgInfo == nullptr) { + jpeg_finish_decompress(&cinfo); + jpeg_destroy_decompress(&cinfo); + fclose(infile); + srcType_ = IMG_SRC_UNKNOWN; + return false; + } + uint8_t* srcData = static_cast(UIMalloc(dataSize)); + if (srcData == nullptr) { + jpeg_finish_decompress(&cinfo); + jpeg_destroy_decompress(&cinfo); + fclose(infile); + UIFree(imgInfo); + srcType_ = IMG_SRC_UNKNOWN; + return false; + } + uint32_t n = 0; + while (cinfo.output_scanline < cinfo.output_height) { + jpeg_read_scanlines(&cinfo, buffer, 1); // 1: read one line each time + for (uint16_t x = 0; x < width * 3; x += 3) { // 3: color components per pixel + srcData[n++] = buffer[0][x + 2]; // 2: B channel + srcData[n++] = buffer[0][x + 1]; // 1: G channel + srcData[n++] = buffer[0][x + 0]; // 0: R channel + srcData[n++] = 255; // 255: set alpha channel + } + } + jpeg_finish_decompress(&cinfo); + jpeg_destroy_decompress(&cinfo); + fclose(infile); + + imgInfo->header.width = width; + imgInfo->header.height = height; + imgInfo->header.colorMode = ARGB8888; + imgInfo->dataSize = dataSize; + imgInfo->data = srcData; + + if (imageInfo_ != nullptr) { + if (mallocFlag_) { + if (imageInfo_->data != nullptr) { + UIFree(reinterpret_cast(const_cast(imageInfo_->data))); + } + mallocFlag_ = false; + } + UIFree(reinterpret_cast(const_cast(imageInfo_))); + imageInfo_ = nullptr; + } + imageInfo_ = imgInfo; + mallocFlag_ = true; + srcType_ = IMG_SRC_VARIABLE; + return true; +} +#endif +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/common/input_device_manager.cpp b/frameworks/common/input_device_manager.cpp new file mode 100755 index 0000000..23923b0 --- /dev/null +++ b/frameworks/common/input_device_manager.cpp @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "common/input_device_manager.h" +#include "common/task_manager.h" +#include "graphic_log.h" + +namespace OHOS { +void InputDeviceManager::Init() +{ + if (INDEV_READ_PERIOD > 0) { + SetPeriod(INDEV_READ_PERIOD); + TaskManager::GetInstance()->Add(this); + } +} + +void InputDeviceManager::Add(InputDevice* device) +{ + if (device == nullptr) { + GRAPHIC_LOGE("InputDeviceManager::Add invalid param\n"); + return; + } + deviceList_.PushBack(device); +} + +void InputDeviceManager::Remove(InputDevice* device) +{ + if (device == nullptr) { + return; + } + ListNode* node = deviceList_.Begin(); + while (node != deviceList_.End()) { + if (node->data_ == device) { + deviceList_.Remove(node); + return; + } + node = node->next_; + } +} + +void InputDeviceManager::Callback() +{ + ListNode* node = deviceList_.Begin(); + while (node != deviceList_.End()) { + node->data_->ProcessEvent(); + node = node->next_; + } +} + +void InputDeviceManager::Clear() +{ + deviceList_.Clear(); +} +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/common/screen.cpp b/frameworks/common/screen.cpp new file mode 100755 index 0000000..0e51e1f --- /dev/null +++ b/frameworks/common/screen.cpp @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "common/screen.h" +#include "dock/screen_device_proxy.h" + +namespace OHOS { +uint16_t Screen::GetWidth() +{ + return ScreenDeviceProxy::GetInstance()->GetScreenWidth(); +} + +uint16_t Screen::GetHeight() +{ + return ScreenDeviceProxy::GetInstance()->GetScreenHeight(); +} +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/common/screen_device_proxy.cpp b/frameworks/common/screen_device_proxy.cpp new file mode 100644 index 0000000..b8d94bd --- /dev/null +++ b/frameworks/common/screen_device_proxy.cpp @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "dock/screen_device_proxy.h" +#include "draw/draw_utils.h" +#include "graphic_log.h" +#include "securec.h" + +namespace OHOS { +#if ENABLE_FRAME_BUFFER +void ScreenDeviceProxy::Flush() {} +#else +void ScreenDeviceProxy::Flush() +{ + flush_.Flushing(); + + if (device_ != nullptr) { +#if ENABLE_WINDOW + device_->Flush(bufferRect_.GetLeft(), bufferRect_.GetTop(), bufferRect_.GetRight(), bufferRect_.GetBottom(), + gfxAlloc_.virAddr, ARGB8888); +#else + device_->Flush(bufferRect_.GetLeft(), bufferRect_.GetTop(), bufferRect_.GetRight(), bufferRect_.GetBottom(), + buffer_, ARGB8888); +#endif + } +} +#endif + +void ScreenDeviceProxy::OnFlushReady() +{ + flush_.Notify(); +} + +void ScreenDeviceProxy::OnRenderFinish() +{ + if (device_ != nullptr) { + device_->RenderFinish(); + } +} + +void ScreenDeviceProxy::DrawAnimatorBuffer(const Rect& invalidatedArea) +{ + Rect invalidRect = curViewRect_; + transMap_.SetTransMapRect(curViewRect_); + invalidRect.Join(invalidRect, transMap_.GetBoxRect()); + + if (invalidRect.Intersect(invalidRect, invalidatedArea)) { + uint8_t pxSize = DrawUtils::GetPxSizeByColorMode(animatorImageInfo_.header.colorMode); + TransformDataInfo imageTranDataInfo = {animatorImageInfo_.header, animatorImageInfo_.data, pxSize, LEVEL0, + BILINEAR}; + DrawUtils::GetInstance()->DrawTransform(invalidRect, {0, 0}, Color::Black(), OPA_OPAQUE, transMap_, + imageTranDataInfo); + } +} + +void ScreenDeviceProxy::SetAnimatorRect(const Rect& rect) +{ + curViewRect_ = rect; + uint16_t bufferWidth = (width_ > curViewRect_.GetWidth()) ? curViewRect_.GetWidth() : width_; + uint16_t bufferHeight = (height_ > curViewRect_.GetHeight()) ? curViewRect_.GetHeight() : height_; + + animatorImageInfo_.header.colorMode = animatorBufferMode_; + animatorImageInfo_.dataSize = bufferWidth * bufferHeight * DrawUtils::GetByteSizeByColorMode(animatorBufferMode_); + animatorImageInfo_.header.width = bufferWidth; + animatorImageInfo_.header.height = bufferHeight; + animatorImageInfo_.header.reserved = 0; + animatorImageInfo_.data = reinterpret_cast(GetBuffer()); + if (animatorImageInfo_.data == nullptr) { + return; + } + + SetAnimatorbufferWidth(bufferWidth); + if (memset_s(reinterpret_cast(const_cast(animatorImageInfo_.data)), animatorImageInfo_.dataSize, 0, + animatorImageInfo_.dataSize) != EOK) { + GRAPHIC_LOGE("animator buffer memset failed."); + } +} + +void ScreenDeviceProxy::SetScreenSize(uint16_t width, uint16_t height) +{ + if ((width == 0) || (height == 0)) { + GRAPHIC_LOGE("screen size can not be zero."); + return; + } + width_ = width; + height_ = height; +#if !ENABLE_WINDOW && !ENABLE_FRAME_BUFFER + if (buffer_ != nullptr) { + UIFree(buffer_); + } + uint32_t bufSize = width * height * DrawUtils::GetByteSizeByColorMode(ARGB8888); + buffer_ = static_cast(UIMalloc(bufSize)); + if (buffer_ == nullptr) { + GRAPHIC_LOGE("screen buffer malloc failed."); + return; + } + if (memset_s(buffer_, bufSize, 0, bufSize) != EOK) { + GRAPHIC_LOGE("screen buffer memset failed."); + UIFree(reinterpret_cast(buffer_)); + buffer_ = nullptr; + } +#endif +} + +uint8_t* ScreenDeviceProxy::GetBuffer() +{ + flush_.Wait(); + if (useAnimatorBuff_) { + if (animatorBufferAddr_ == nullptr) { + GRAPHIC_LOGE("Invalid param animatorBufferAddr_."); + return nullptr; + } + int32_t offset = bufferRect_.GetTop() * animatorBufferWidth_ + bufferRect_.GetLeft(); + offset *= DrawUtils::GetByteSizeByColorMode(animatorBufferMode_); + return animatorBufferAddr_ + offset; + } +#if ENABLE_FRAME_BUFFER + if (frameBufferAddr_ == nullptr) { + GRAPHIC_LOGE("Invalid param frameBufferAddr_."); + return nullptr; + } + int32_t offset = bufferRect_.GetTop() * frameBufferWidth_ + bufferRect_.GetLeft(); + offset *= DrawUtils::GetByteSizeByColorMode(frameBufferMode_); + return frameBufferAddr_ + offset; +#elif ENABLE_WINDOW + return gfxAlloc_.virAddr; +#else + return buffer_; +#endif +} + +ColorMode ScreenDeviceProxy::GetBufferMode() +{ + if (useAnimatorBuff_) { + return animatorBufferMode_; + } +#if ENABLE_FRAME_BUFFER + return frameBufferMode_; +#else + return ARGB8888; +#endif +} +} // namespace OHOS diff --git a/frameworks/common/task.cpp b/frameworks/common/task.cpp new file mode 100755 index 0000000..a38827a --- /dev/null +++ b/frameworks/common/task.cpp @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ +#include "common/task.h" +#include "common/task_manager.h" +#include "hal_tick.h" + +namespace OHOS { +void Task::TaskExecute() +{ + uint32_t elp = HALTick::GetInstance().GetElapseTime(lastRun_); + if (elp >= period_) { + lastRun_ = HALTick::GetInstance().GetTime(); + Callback(); + } +} + +void Task::Init() +{ + SetPeriod(period_); + TaskManager::GetInstance()->Add(this); +} +} diff --git a/frameworks/common/text.cpp b/frameworks/common/text.cpp new file mode 100755 index 0000000..de1bb32 --- /dev/null +++ b/frameworks/common/text.cpp @@ -0,0 +1,368 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "common/text.h" +#include "common/typed_text.h" +#include "draw/draw_label.h" +#include "font/ui_font.h" +#include "graphic_log.h" +#include "securec.h" + +namespace OHOS { +Text::TextLine Text::textLine_[MAX_LINE_COUNT] = {{0}}; + +Text::Text() + : text_(nullptr), + fontId_(0), + fontSize_(0), + textSize_({0, 0}), + needRefresh_(false), + expandWidth_(false), + expandHeight_(false), + direct_(TEXT_DIRECT_LTR), + horizontalAlign_(TEXT_ALIGNMENT_LEFT), + verticalAlign_(TEXT_ALIGNMENT_TOP) +{ + SetFont(DEFAULT_VECTOR_FONT_FILENAME, DEFAULT_VECTOR_FONT_SIZE); +} + +Text::~Text() +{ + if (text_ != nullptr) { + UIFree(text_); + text_ = nullptr; + } +} + +void Text::SetText(const char* text) +{ + if (text == nullptr) { + return; + } + uint32_t textLen = static_cast(strlen(text)); + if (textLen > MAX_TEXT_LENGTH) { + return; + } + if (text_ != nullptr) { + if (strcmp(text, text_) == 0) { + return; + } + UIFree(text_); + text_ = nullptr; + } + text_ = static_cast(UIMalloc(++textLen)); + if (text_ == nullptr) { + return; + } + if (memcpy_s(text_, textLen, text, textLen) != EOK) { + UIFree(text_); + text_ = nullptr; + return; + } + needRefresh_ = true; +} + +void Text::SetFont(const char* name, uint8_t size) +{ + if (name == nullptr) { + return; + } + if (UIFont::GetInstance()->IsVectorFont()) { + uint8_t fontId = UIFont::GetInstance()->GetFontId(name); + if ((fontId != GetTotalFontId()) && ((fontId_ != fontId) || (fontSize_ != size))) { + fontId_ = fontId; + fontSize_ = size; + needRefresh_ = true; + } + } else { + uint8_t fontId = UIFont::GetInstance()->GetFontId(name, size); + SetFontId(fontId); + } +} + +void Text::SetFont(const char* name, uint8_t size, char*& destName, uint8_t& destSize) +{ + if (name == nullptr) { + return; + } + uint32_t nameLen = static_cast(strlen(name)); + if (nameLen > MAX_TEXT_LENGTH) { + return; + } + if (destName != nullptr) { + if (strcmp(destName, name) == 0) { + destSize = size; + return; + } + UIFree(destName); + destName = nullptr; + } + if (nameLen != 0) { + /* one more to store '\0' */ + destName = static_cast(UIMalloc(++nameLen)); + if (destName == nullptr) { + return; + } + if (memcpy_s(destName, nameLen, name, nameLen) != EOK) { + UIFree(destName); + destName = nullptr; + return; + } + destSize = size; + } +} + +void Text::SetFontId(uint8_t fontId) +{ + if ((fontId >= GetTotalFontId()) || (fontId_ == fontId)) { + GRAPHIC_LOGE("Text::SetFontId invalid fontId(%d)", fontId); + return; + } + UITextLanguageFontParam* fontParam = GetTextLangFontsTable(fontId); + if (fontParam == nullptr) { + return; + } + if (UIFont::GetInstance()->IsVectorFont()) { + uint8_t fontId = UIFont::GetInstance()->GetFontId(fontParam->ttfName); + if ((fontId != GetTotalFontId()) && ((fontId_ != fontId) || (fontSize_ != fontParam->size))) { + fontId_ = fontId; + fontSize_ = fontParam->size; + needRefresh_ = true; + } + } else { + fontId_ = fontId; + fontSize_ = fontParam->size; + needRefresh_ = true; + } +} + +void Text::ReMeasureTextSize(const Rect& textRect, const Style& style) +{ + if (fontSize_ == 0) { + return; + } + UIFont::GetInstance()->SetCurrentFontId(fontId_, fontSize_); + int16_t maxWidth = (expandWidth_ ? COORD_MAX : textRect.GetWidth()); + if (maxWidth > 0) { + textSize_ = TypedText::GetTextSize(text_, style.letterSpace_, style.lineSpace_, maxWidth); + FontHeader head; + if (UIFont::GetInstance()->GetCurrentFontHeader(head) != 0) { + return; + } + textSize_.y += fontSize_ - head.ascender; + } +} + +void Text::OnDraw(const Rect& invalidatedArea, + const Rect& viewOrigRect, + const Rect& textRect, + int16_t offsetX, + const Style& style, + uint16_t ellipsisIndex, + OpacityType opaScale) +{ + if ((text_ == nullptr) || (strlen(text_) == 0) || (fontSize_ == 0)) { + return; + } + UIFont::GetInstance()->SetCurrentFontId(fontId_, fontSize_); + Rect mask = invalidatedArea; + + if (mask.Intersect(mask, textRect)) { + Draw(mask, textRect, style, offsetX, ellipsisIndex, opaScale); + } +} + +void Text::Draw(const Rect& mask, + const Rect& coords, + const Style& style, + int16_t offsetX, + uint16_t ellipsisIndex, + OpacityType opaScale) +{ + Point offset = {offsetX, 0}; + int16_t lineMaxWidth = expandWidth_ ? textSize_.x : coords.GetWidth(); + int16_t lineHeight = UIFont::GetInstance()->GetHeight() + style.lineSpace_; + uint16_t lineBegin = 0; + uint32_t maxLineBytes = 0; + uint16_t lineCount = GetLine(lineMaxWidth, style.letterSpace_, ellipsisIndex, maxLineBytes); + Point pos; + pos.y = TextPositionY(coords, (lineCount * lineHeight - style.lineSpace_)); + OpacityType opa = DrawUtils::GetMixOpacity(opaScale, style.textOpa_); + for (int i = 0; i < lineCount; i++) { + if (pos.y > mask.GetBottom()) { + return; + } + int16_t nextLine = pos.y + lineHeight; + if (nextLine >= mask.GetTop()) { + pos.x = LineStartPos(coords, textLine_[i].linePixelWidth); + LabelLineInfo labelLine{pos, + offset, + mask, + lineHeight, + textLine_[i].lineBytes, + 0, + opa, + style, + &text_[lineBegin], + textLine_[i].lineBytes, + lineBegin, + fontId_, + fontSize_, + 0, + static_cast(direct_), + nullptr}; + DrawLabel::DrawTextOneLine(labelLine); + if ((i == (lineCount - 1)) && (ellipsisIndex != TEXT_ELLIPSIS_END_INV)) { + labelLine.offset.x = 0; + labelLine.text = TEXT_ELLIPSIS; + labelLine.lineLength = TEXT_ELLIPSIS_DOT_NUM; + labelLine.length = TEXT_ELLIPSIS_DOT_NUM; + DrawLabel::DrawTextOneLine(labelLine); + } + } + lineBegin += textLine_[i].lineBytes; + pos.y = nextLine; + } +} + +int16_t Text::TextPositionY(const Rect& textRect, int16_t textHeight) +{ + int16_t yOffset = 0; + if (!expandHeight_ && (verticalAlign_ != TEXT_ALIGNMENT_TOP) && (textRect.GetHeight() > textHeight)) { + if (verticalAlign_ == TEXT_ALIGNMENT_CENTER) { + yOffset = (textRect.GetHeight() - textHeight) >> 1; + } else if (verticalAlign_ == TEXT_ALIGNMENT_BOTTOM) { + yOffset = textRect.GetHeight() - textHeight; + } + } + return textRect.GetY() + yOffset; +} + +int16_t Text::LineStartPos(const Rect& textRect, uint16_t lineWidth) +{ + int16_t xOffset = 0; + int16_t rectWidth = textRect.GetWidth(); + if (horizontalAlign_ == TEXT_ALIGNMENT_CENTER) { + xOffset = (direct_ == TEXT_DIRECT_RTL) ? ((rectWidth + lineWidth + 1) >> 1) : ((rectWidth - lineWidth) >> 1); + } else if (horizontalAlign_ == TEXT_ALIGNMENT_RIGHT) { + xOffset = (direct_ == TEXT_DIRECT_RTL) ? rectWidth : (rectWidth - lineWidth); + } else { + xOffset = (direct_ == TEXT_DIRECT_RTL) ? lineWidth : 0; + } + return textRect.GetX() + xOffset; +} + +uint16_t Text::GetLine(int16_t width, uint8_t letterSpace, uint16_t ellipsisIndex, uint32_t& maxLineBytes) +{ + if (text_ == nullptr) { + return 0; + } + uint16_t lineNum = 0; + uint32_t textLen = GetTextStrLen(); + if ((ellipsisIndex != TEXT_ELLIPSIS_END_INV) && (ellipsisIndex < textLen)) { + textLen = ellipsisIndex; + } + uint32_t begin = 0; + while ((begin < textLen) && (text_[begin] != '\0') && (lineNum < MAX_LINE_COUNT)) { + begin += GetTextLine(begin, textLen, width, lineNum, letterSpace); + if (maxLineBytes < textLine_[lineNum].lineBytes) { + maxLineBytes = textLine_[lineNum].lineBytes; + } + lineNum++; + } + if ((lineNum != 0) && (ellipsisIndex != TEXT_ELLIPSIS_END_INV)) { + uint16_t ellipsisWidth = UIFont::GetInstance()->GetWidth('.', 0) + letterSpace; + textLine_[lineNum - 1].linePixelWidth += ellipsisWidth * TEXT_ELLIPSIS_DOT_NUM; + } + return lineNum; +} + +uint32_t Text::GetTextStrLen() +{ + return strlen(text_); +} + +uint32_t Text::GetTextLine(uint32_t begin, uint32_t textLen, int16_t width, uint16_t lineNum, uint8_t letterSpace) +{ + uint16_t nextLineBytes = TypedText::GetNextLine(&text_[begin], letterSpace, width); + if (nextLineBytes + begin > textLen) { + nextLineBytes = textLen - begin; + } + textLine_[lineNum].lineBytes = nextLineBytes; + textLine_[lineNum].linePixelWidth = + static_cast(TypedText::GetTextWidth(&text_[begin], nextLineBytes, letterSpace)); + return nextLineBytes; +} + +uint16_t Text::GetEllipsisIndex(const Rect& textRect, const Style& style) +{ + if ((textSize_.y <= textRect.GetHeight()) || (TypedText::GetUTF8CharacterSize(text_) <= TEXT_ELLIPSIS_DOT_NUM)) { + return TEXT_ELLIPSIS_END_INV; + } + UIFont* fontEngine = UIFont::GetInstance(); + fontEngine->SetCurrentFontId(fontId_, fontSize_); + int16_t letterWidth = fontEngine->GetWidth('.', 0) + style.letterSpace_; + Point p; + p.x = textRect.GetWidth() - letterWidth * TEXT_ELLIPSIS_DOT_NUM; + p.y = textRect.GetHeight(); + int16_t height = fontEngine->GetHeight() + style.lineSpace_; + if (height) { + p.y -= p.y % height; + } + + p.y -= style.lineSpace_; + return GetLetterIndexByPosition(textRect, style, p); +} + +uint16_t Text::GetLetterIndexByPosition(const Rect& textRect, const Style& style, const Point& pos) +{ + if (text_ == nullptr) { + return 0; + } + uint32_t lineStart = 0; + uint32_t nextLineStart = 0; + + uint16_t lineHeight = UIFont::GetInstance()->GetHeight(); + int16_t y = 0; + uint32_t textLen = static_cast(strlen(text_)); + while ((lineStart < textLen) && (text_[lineStart] != '\0')) { + nextLineStart += TypedText::GetNextLine(&text_[lineStart], style.letterSpace_, textRect.GetWidth()); + if (pos.y <= y + lineHeight) { + break; + } + y += lineHeight + style.lineSpace_; + lineStart = nextLineStart; + } + /* Calculate the x coordinate */ + int16_t x = 0; + uint32_t i = lineStart; + uint32_t pre = i; + while (i < nextLineStart - 1) { + uint32_t letter = TypedText::GetUTF8Next(text_, i, i); + x += UIFont::GetInstance()->GetWidth(letter, 0); + if (pos.x < x) { + i = pre; + break; + } + x += style.letterSpace_; + pre = i; + } + if (i >= (GetTextStrLen() - TEXT_ELLIPSIS_DOT_NUM)) { + return TEXT_ELLIPSIS_END_INV; + } else { + return static_cast(i); + } +} +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/common/typed_text.cpp b/frameworks/common/typed_text.cpp new file mode 100755 index 0000000..63e3780 --- /dev/null +++ b/frameworks/common/typed_text.cpp @@ -0,0 +1,384 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "common/typed_text.h" +#include "font/ui_font.h" +#include "font/ui_font_adaptor.h" +#include "graphic_log.h" +#include "mem_api.h" +#include "transform.h" + +namespace OHOS { +#ifndef _FONT_TOOL +Point TypedText::GetTextSize(const char* text, int16_t letterSpace, int16_t lineSpace, int16_t maxWidth) +{ + Point size{0, 0}; + + if (text == nullptr) { + GRAPHIC_LOGE("TypedText::GetTextSize invalid parameter"); + return size; + } + + uint32_t lineBegin = 0; + uint32_t newLineBegin = 0; + uint16_t letterHeight = UIFont::GetInstance()->GetHeight(); + + while (text[lineBegin] != '\0') { + int16_t lineWidth = maxWidth; + newLineBegin += UIFontAdaptor::GetNextLineAndWidth(&text[lineBegin], letterSpace, lineWidth); + if (newLineBegin == lineBegin) { + break; + } + size.y += letterHeight + lineSpace; + size.x = MATH_MAX(lineWidth, size.x); + lineBegin = newLineBegin; + } + + if ((lineBegin != 0) && ((text[lineBegin - 1] == '\n') || (text[lineBegin - 1] == '\r'))) { + size.y += letterHeight + lineSpace; + } + + if (size.y == 0) { + size.y = letterHeight; + } else { + size.y -= lineSpace; + } + return size; +} + +Rect TypedText::GetArcTextRect(const char* text, + const Point& arcCenter, + int16_t letterSpace, + UIArcLabel::TextOrientation orientation, + const UIArcLabel::ArcTextInfo& arcTextInfo) +{ + if ((text == nullptr) || (arcTextInfo.lineStart == arcTextInfo.lineEnd) || (arcTextInfo.radius == 0)) { + GRAPHIC_LOGE("TypedText::GetArcTextRect invalid parameter\n"); + return Rect(); + } + + uint16_t letterHeight = UIFont::GetInstance()->GetHeight(); + bool xorFlag = (orientation == UIArcLabel::TextOrientation::INSIDE) ^ (arcTextInfo.direct == TEXT_DIRECT_LTR); + float posX = 0; + float posY = 0; + uint32_t i = arcTextInfo.lineStart; + float angle = arcTextInfo.startAngle; + Rect rect; + Rect rectLetter; + TransformMap transform; + while (i < arcTextInfo.lineEnd) { + uint32_t tmp = i; + uint32_t letter = GetUTF8Next(text, tmp, i); + if (letter == 0) { + continue; + } + if ((letter == '\r') || (letter == '\n')) { + break; + } + uint16_t letterWidth = UIFont::GetInstance()->GetWidth(letter, 0); + if (tmp == arcTextInfo.lineStart) { + angle += xorFlag ? GetAngleForArcLen(static_cast(letterWidth), letterHeight, arcTextInfo.radius, + arcTextInfo.direct, orientation) + : 0; + GetArcLetterPos(arcCenter, arcTextInfo.radius, angle, posX, posY); + rect.SetPosition(MATH_ROUND(posX), MATH_ROUND(posY)); + } + rectLetter.SetPosition(MATH_ROUND(posX), MATH_ROUND(posY)); + rectLetter.Resize(letterWidth, letterHeight); + transform.SetTransMapRect(rectLetter); + + uint16_t arcLen = letterWidth + letterSpace; + if (arcLen == 0) { + continue; + } + float incrementAngle = GetAngleForArcLen(static_cast(arcLen), letterHeight, arcTextInfo.radius, + arcTextInfo.direct, orientation); + float rotateAngle = + (orientation == UIArcLabel::TextOrientation::INSIDE) ? angle : (angle - SEMICIRCLE_IN_DEGREE); + // 2: letterWidth's half + float fineTuningAngle = incrementAngle * (static_cast(letterWidth) / (2 * arcLen)); + rotateAngle += (xorFlag ? -fineTuningAngle : fineTuningAngle); + + transform.Rotate(MATH_ROUND(rotateAngle), Vector2(0, 0)); + rect.Join(rect, transform.GetBoxRect()); + + angle += incrementAngle; + GetArcLetterPos(arcCenter, arcTextInfo.radius, angle, posX, posY); + } + return rect; +} + +float TypedText::GetAngleForArcLen(float len, + uint16_t height, + uint16_t radius, + UITextLanguageDirect direct, + UIArcLabel::TextOrientation orientation) +{ + float realRadius = + static_cast((orientation == UIArcLabel::TextOrientation::OUTSIDE) ? (radius + height) : radius); + float angle = static_cast(len * SEMICIRCLE_IN_DEGREE) / (UI_PI * realRadius); + return (direct == TEXT_DIRECT_LTR) ? angle : -angle; +} + +void TypedText::GetArcLetterPos(const Point& arcCenter, uint16_t radius, float angle, float& posX, float& posY) +{ + posX = arcCenter.x + (static_cast(radius) * Sin(MATH_ROUND(angle))); + posY = arcCenter.y - (static_cast(radius) * Sin(MATH_ROUND(angle + QUARTER_IN_DEGREE))); +} + +uint32_t TypedText::GetNextLine(const char* text, int16_t letterSpace, int16_t maxWidth) +{ + uint32_t lastBreakPos = 0; + int16_t curW; + uint32_t index = 0; + uint32_t tmp = 0; + if (GetWrapPoint(text, index)) { + return index; + } + while (true) { + curW = TypedText::GetTextWidth(text, index, letterSpace); + if (curW > maxWidth) { + index = lastBreakPos; + if (lastBreakPos == 0) { + curW = 0; + uint32_t i = 0; + uint32_t letter; + uint16_t letterWidth; + while (text[i] != '\0') { + tmp = i; + letter = TypedText::GetUTF8Next(text, tmp, i); + letterWidth = UIFont::GetInstance()->GetWidth(letter, 0); + curW += letterWidth; + if (letterWidth > 0) { + curW += letterSpace; + } + if (curW > maxWidth) { + index = lastBreakPos; + return index; + } + lastBreakPos = i; + } + } + break; + } + if ((index > 0) && (index < strlen(text)) && ((text[index - 1] == '\r') || (text[index - 1] == '\n'))) { + break; + } + lastBreakPos = index; + if (text[index] == '\0') { + break; + } + if (GetWrapPoint(text + index, tmp)) { + return index + tmp; + } + index += tmp; + if (lastBreakPos == index) { + break; + } + } + return index; +} + +bool TypedText::GetWrapPoint(const char* text, uint32_t& breakPoint) +{ + breakPoint = 0; + uint32_t j = 0; + uint32_t letter = 0; + if (text == nullptr) { + return true; + } + + while (text[breakPoint] != '\0') { + letter = GetUTF8Next(text, breakPoint, j); + breakPoint = j; + if ((letter == ' ') || (letter == '.') || (letter == ',') || (letter == '!') || (letter == '=') + || (letter == '?')) { + return false; + } + if (letter == '\n') { + return true; + } + if ((letter == '\r') && (GetUTF8Next(text, breakPoint, j) == '\n')) { + breakPoint = j; + return true; + } + } + return false; +} + +int16_t TypedText::GetTextWidth(const char* text, uint16_t length, int16_t letterSpace) +{ + if ((text == nullptr) || (length == 0) || (length > strlen(text))) { + GRAPHIC_LOGE("TypedText::GetTextWidth invalid parameter\n"); + return 0; + } + + uint32_t i = 0; + uint16_t width = 0; + uint32_t letter; + + while (i < length) { + letter = GetUTF8Next(text, i, i); + if ((letter == 0) || (letter == '\n') || (letter == '\r')) { + continue; + } + uint16_t charWidth = UIFont::GetInstance()->GetWidth(letter, 0); + width += charWidth + letterSpace; + } + if (width > 0) { + width -= letterSpace; + } + return width; +} +#endif // _FONT_TOOL + +uint8_t TypedText::GetUTF8OneCharacterSize(const char* str) +{ + if ((str[0] & 0x80) == 0) { + return 1; + } else if ((str[0] & 0xE0) == 0xC0) { + return 2; // 2: 2 bytes + } else if ((str[0] & 0xF0) == 0xE0) { + return 3; // 3: 3 bytes + } else if ((str[0] & 0xF8) == 0xF0) { + return 4; // 4: 4 bytes + } + return 0; +} + +uint32_t TypedText::GetUTF8Next(const char* text, uint32_t i, uint32_t& j) +{ + uint32_t unicode = 0; + if (text == nullptr) { + GRAPHIC_LOGE("text invalid parameter"); + return 0; + } + + j = i; + uint8_t lettetSize = GetUTF8OneCharacterSize(text + i); + switch (lettetSize) { + case 1: + unicode = text[j]; + break; + case 2: // 2: letter size + unicode = static_cast(text[j] & 0x1F) << UTF8_TO_UNICODE_SHIFT1; + j++; + if ((text[j] & 0xC0) != 0x80) { + return 0; + } + unicode += (text[j] & 0x3F); + break; + case 3: // 3: letter size + unicode = static_cast(text[j] & 0x0F) << UTF8_TO_UNICODE_SHIFT2; + unicode += static_cast(text[++j] & 0x3F) << UTF8_TO_UNICODE_SHIFT1; + unicode += (text[++j] & 0x3F); + break; + case 4: // 4: letter size + unicode = static_cast(text[j] & 0x07) << UTF8_TO_UNICODE_SHIFT3; + unicode += static_cast(text[++j] & 0x3F) << UTF8_TO_UNICODE_SHIFT2; + unicode += static_cast(text[++j] & 0x3F) << UTF8_TO_UNICODE_SHIFT1; + unicode += text[++j] & 0x3F; + break; + default: + break; + } + j++; + return unicode; +} + +uint32_t TypedText::GetByteIndexFromUTF8Id(const char* text, uint32_t utf8Id) +{ + if (text == nullptr) { + GRAPHIC_LOGE("TypedText::GetByteIndexFromUTF8Id text invalid parameter\n"); + return 0; + } + uint32_t byteIndex = 0; + for (uint32_t i = 0; i < utf8Id; i++) { + byteIndex += GetUTF8OneCharacterSize(&text[byteIndex]); + } + + return byteIndex; +} + +uint32_t TypedText::GetUTF8CharacterSize(const char* text, uint32_t byteIndex) +{ + uint32_t i = 0; + uint32_t size = 0; + + if (text == nullptr) { + GRAPHIC_LOGE("TypedText::GetUTF8CharacterSize text invalid parameter\n"); + return 0; + } + while ((text[i] != '\0') && (i < byteIndex)) { + GetUTF8Next(text, i, i); + size++; + } + + return size; +} + +void TypedText::Utf8ToUtf16(const char* utf8Str, uint16_t* utf16Str, uint32_t len) +{ + if ((utf8Str == nullptr) || (utf16Str == nullptr)) { + GRAPHIC_LOGE("utf8Str or u16Str is null"); + return; + } + + uint32_t i = 0; + uint32_t cnt = 0; + while (utf8Str[i] != '\0') { + uint32_t unicode = GetUTF8Next(utf8Str, i, i); + if (cnt < len) { + if (unicode <= MAX_UINT16_LOW_SCOPE) { + utf16Str[cnt] = (unicode & MAX_UINT16_LOW_SCOPE); + } else if (unicode <= MAX_UINT16_HIGH_SCOPE) { + if (cnt + 1 < len) { + utf16Str[cnt] = static_cast(UTF16_LOW_PARAM + (unicode & UTF16_LOW_MASK)); // low + cnt++; + utf16Str[cnt] = static_cast(UTF16_HIGH_PARAM1 + (unicode >> UTF16_HIGH_SHIFT) - + UTF16_HIGH_PARAM2); // high + } + } else { + GRAPHIC_LOGE("Invalid unicode"); + return; + } + cnt++; + } + } +} + +uint32_t TypedText::GetUtf16Cnt(const char* utf8Str) +{ + if (utf8Str == nullptr) { + GRAPHIC_LOGE("text invalid parameter"); + return 0; + } + uint32_t len = 0; + uint32_t i = 0; + + while (utf8Str[i] != '\0') { + uint32_t unicode = GetUTF8Next(utf8Str, i, i); + if (unicode <= MAX_UINT16_LOW_SCOPE) { + len++; + } else if (unicode <= MAX_UINT16_HIGH_SCOPE) { + len += 2; // 2: low and high, two uint16_t numbers + } else { + GRAPHIC_LOGE("Invalid unicode"); + return 0; + } + } + return len; +} +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/common/typed_text.h b/frameworks/common/typed_text.h new file mode 100755 index 0000000..6dbba99 --- /dev/null +++ b/frameworks/common/typed_text.h @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef GRAPHIC_LITE_TYPE_TEXT_H +#define GRAPHIC_LITE_TYPE_TEXT_H +#include "common/text.h" +#include "graphic_config.h" +#ifndef _FONT_TOOL +#include "components/ui_arc_label.h" +#include "font/ui_font_header.h" +#include "geometry2d.h" +#endif + +namespace OHOS { +#ifndef _FONT_TOOL +class TypedText : public HeapBase { +public: + static constexpr uint32_t MAX_UINT16_LOW_SCOPE = 0xFFFF; + static constexpr uint32_t MAX_UINT16_HIGH_SCOPE = 0xEFFFF; + static constexpr uint32_t UTF16_LOW_MASK = 0x03FF; + static constexpr uint32_t UTF16_LOW_PARAM = 56320; + static constexpr uint32_t UTF16_HIGH_PARAM1 = 55296; + static constexpr uint8_t UTF16_HIGH_PARAM2 = 64; + static constexpr uint8_t UTF16_HIGH_SHIFT = 10; + static constexpr uint8_t UTF8_TO_UNICODE_SHIFT1 = 6; + static constexpr uint8_t UTF8_TO_UNICODE_SHIFT2 = 12; + static constexpr uint8_t UTF8_TO_UNICODE_SHIFT3 = 18; + + static Point GetTextSize(const char* text, + int16_t letterSpace, + int16_t lineSpace, + int16_t maxWidth); + + static uint32_t GetNextLine(const char* text, + int16_t letterSpace, + int16_t maxWidth); + + static int16_t GetTextWidth(const char* text, + uint16_t length, + int16_t letterSpace); + + static Rect GetArcTextRect(const char* text, + const Point& arcCenter, + int16_t letterSpace, + UIArcLabel::TextOrientation orientation, + const UIArcLabel::ArcTextInfo& arcTextInfo); + + static float GetAngleForArcLen(float len, + uint16_t height, + uint16_t radius, + UITextLanguageDirect direct, + UIArcLabel::TextOrientation orientation); + + static void GetArcLetterPos(const Point& arcCenter, uint16_t radius, float angle, float& posX, float& posY); + +#else // _FONT_TOOL +class TypedText { +public: +#endif // _FONT_TOOL + static uint32_t GetUTF8Next(const char* text, uint32_t i, uint32_t& j); + static uint8_t GetUTF8OneCharacterSize(const char* str); + static uint32_t GetByteIndexFromUTF8Id(const char* text, uint32_t utf8Id); + static uint32_t GetUTF8CharacterSize(const char* text, uint32_t byteIndex = UINT32_MAX); + static void Utf8ToUtf16(const char* utf8Str, uint16_t* utf16Str, uint32_t len); + static uint32_t GetUtf16Cnt(const char* utf8Str); + +private: + static bool GetWrapPoint(const char* text, uint32_t& breakPoint); +}; +} // namespace OHOS +#endif // GRAPHIC_LITE_TYPE_TEXT_H diff --git a/frameworks/common/ui_font_header.cpp b/frameworks/common/ui_font_header.cpp new file mode 100755 index 0000000..df03018 --- /dev/null +++ b/frameworks/common/ui_font_header.cpp @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "font/ui_font.h" +#include "font/ui_font_header.h" + +namespace OHOS { +UITextLanguageFontParam* GetTextLangFontsTable(uint8_t langFontId) +{ + // Need to be implemented + return nullptr; +} + +uint8_t GetTotalLangId() +{ + // Need to be implemented + return 0; +} + +uint8_t GetBitmapFontIdMax() +{ + // Need to be implemented + return 0; +} + +uint8_t GetTotalFontId() +{ + // Need to be implemented + return 0xFF; +} + +uint16_t GetTotalTextId() +{ + // Need to be implemented + return 0; +} + +LangTextParam* GetLangTextDefaultParamTable() +{ + // Need to be implemented + return nullptr; +} +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/components/root_view.cpp b/frameworks/components/root_view.cpp new file mode 100755 index 0000000..90199a4 --- /dev/null +++ b/frameworks/components/root_view.cpp @@ -0,0 +1,633 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "components/root_view.h" + +#include "common/screen.h" +#include "core/render_manager.h" +#include "dock/screen_device_proxy.h" +#include "graphic_log.h" +#if ENABLE_WINDOW +#include "window/window_impl.h" +#endif +namespace OHOS { +namespace { +#if LOCAL_RENDER +const constexpr uint8_t MAX_SPLIT_NUM = 32; // split at most 32 parts +// view along with its parents and siblings are at most 128 +const constexpr uint8_t VIEW_STACK_DEPTH = COMPONENT_NESTING_DEPTH * 2; +#else +const constexpr uint8_t VIEW_STACK_DEPTH = COMPONENT_NESTING_DEPTH; +#endif +static Rect g_maskStack[COMPONENT_NESTING_DEPTH]; +static UIView* g_viewStack[VIEW_STACK_DEPTH]; +} // namespace +RootView::RootView() +{ +#if defined __linux__ || defined __LITEOS__ || defined __APPLE__ + pthread_mutex_init(&lock_, nullptr); +#endif +} + +#if ENABLE_WINDOW +Window* RootView::GetBoundWindow() const +{ + return boundWindow_; +} +#endif + +inline bool RootView::IntersectScreenRect(Rect& rect) +{ +#if ENABLE_WINDOW + Rect screenRect = GetRect(); +#else + Rect screenRect(0, 0, Screen::GetInstance().GetWidth() - 1, Screen::GetInstance().GetHeight() - 1); +#endif + return rect.Intersect(rect, screenRect); +} + +#if LOCAL_RENDER +static void DivideInvalidateRect(const Rect& originRect, Rect& leftoverRect, Vector& splitRects) +{ + Rect mask; + if (!mask.Intersect(originRect, leftoverRect)) { + splitRects.PushBack(leftoverRect); + return; + } + + /* + * +---+---+---+ + * | | A | | originRect :A+B + * | +---+ | leftoverRect :A->0 + * | B | mask :A + * +-----------+ + */ + if (originRect.IsContains(leftoverRect)) { + return; + } + + int16_t reserveCnt = MAX_SPLIT_NUM - splitRects.Size(); + if (reserveCnt <= 0) { + splitRects.PushBack(leftoverRect); + return; + } + + if (mask.GetWidth() == leftoverRect.GetWidth()) { + /* + * +---+ + * | A | originRect :B+C + * +-----------+ leftoverRect :A+B->A + * | | B | | mask :B + * | +---+ | + * | C | + * +-----------+ + */ + if (mask.GetBottom() == leftoverRect.GetBottom()) { + leftoverRect.SetBottom(mask.GetTop() - 1); + } else if (mask.GetTop() == leftoverRect.GetTop()) { + leftoverRect.SetTop(mask.GetBottom() + 1); + } else { + splitRects.PushBack(leftoverRect); + splitRects.Back().SetBottom(mask.GetTop() - 1); + leftoverRect.SetTop(mask.GetBottom() + 1); + } + splitRects.PushBack(leftoverRect); + return; + } + if (mask.GetHeight() == leftoverRect.GetHeight()) { + /* + * +---------+ originRect :B+C + * +-------+ | leftoverRect :A+B->A + * | A | B | C | mask :B + * +-------+ | + * +---------+ + */ + if (mask.GetLeft() == leftoverRect.GetLeft()) { + leftoverRect.SetLeft(mask.GetRight() + 1); + } else if (mask.GetRight() == leftoverRect.GetRight()) { + leftoverRect.SetRight(mask.GetLeft() - 1); + } else { + splitRects.PushBack(leftoverRect); + splitRects.Back().SetRight(mask.GetLeft() - 1); + leftoverRect.SetLeft(mask.GetRight() + 1); + } + splitRects.PushBack(leftoverRect); + return; + } + + Vector copyRect(splitRects); + if (mask.GetLeft() != leftoverRect.GetLeft()) { + /* + * | + * +-------+ + * | +---+ mask :A + * | B | A | leftoverRect :A+B + * | +---+ + * +-------+ + * | + */ + if (reserveCnt-- <= 0) { + splitRects.Swap(copyRect); + splitRects.PushBack(leftoverRect); + return; + } + splitRects.PushBack(leftoverRect); + splitRects.Back().SetRight(mask.GetLeft() - 1); + leftoverRect.SetLeft(mask.GetLeft()); + } + + if (mask.GetTop() != leftoverRect.GetTop()) { + /* + * +-------+ + * | B | mask :A + * ---+---+--- leftoverRect :A+B + * | | A | | + * +-+---+-+ + */ + if (reserveCnt-- <= 0) { + splitRects.Swap(copyRect); + splitRects.PushBack(leftoverRect); + return; + } + splitRects.PushBack(leftoverRect); + splitRects.Back().SetBottom(mask.GetTop() - 1); + leftoverRect.SetTop(mask.GetTop()); + } + + if (mask.GetRight() != leftoverRect.GetRight()) { + /* + * | + * +-------+ + * +---+ | mask :A + * | A | B | leftoverRect :A+B + * +---+ | + * +-------+ + * | + */ + if (reserveCnt-- <= 0) { + splitRects.Swap(copyRect); + splitRects.PushBack(leftoverRect); + return; + } + splitRects.PushBack(leftoverRect); + splitRects.Back().SetLeft(mask.GetRight() + 1); + leftoverRect.SetRight(mask.GetRight()); + } + + if (mask.GetBottom() != leftoverRect.GetBottom()) { + /* + * +-+---+-+ + * | | A | | mask :A + * ---+---+--- leftoverRect :A+B + * | B | + * +-------+ + */ + if (reserveCnt-- <= 0) { + splitRects.Swap(copyRect); + splitRects.PushBack(leftoverRect); + return; + } + splitRects.PushBack(leftoverRect); + splitRects.Back().SetTop(mask.GetBottom() + 1); + leftoverRect.SetBottom(mask.GetBottom()); + } + return; +} + +static void AddRenderedRects(Rect& rect, List& renderedRects, ListNode* iter) +{ + /* Elements at front have larger area and more relevance */ + for (; iter != renderedRects.End(); iter = iter->next_) { + Rect& curRect = iter->data_; + if (!curRect.IsIntersect(rect)) { + continue; + } + + if (curRect.IsContains(rect)) { + return; + } + + /* Merge two rects */ + if (rect.IsContains(curRect)) { + } else if (((curRect.GetLeft() == rect.GetLeft()) && (curRect.GetRight() == rect.GetRight())) || + ((curRect.GetTop() == rect.GetTop()) && (curRect.GetBottom() == rect.GetBottom()))) { + rect.Join(curRect, rect); + } else { + continue; + } + iter = renderedRects.Remove(iter)->prev_; + break; + } + if (iter == renderedRects.End()) { // No merge rises + if (renderedRects.Size() == 128) { // record 128 rendered rects at most + renderedRects.PopBack(); + } + renderedRects.PushFront(rect); + } else { // merge rises, go over the rest nodes + AddRenderedRects(rect, renderedRects, iter); + } +} + +void RootView::RemoveViewFromInvalidMap(UIView* view) +{ +#if defined __linux__ || defined __LITEOS__ || defined __APPLE__ + pthread_mutex_lock(&lock_); +#endif + + int16_t stackCount = 0; + do { + while (view != nullptr) { + /* delete node itself */ + auto entry = invalidateMap_.find(view); + if (entry != invalidateMap_.end()) { + invalidateMap_.erase(entry); + } + /* delete node's children */ + if (view->IsViewGroup() && stackCount < COMPONENT_NESTING_DEPTH) { + g_viewStack[stackCount++] = view; + view = static_cast(view)->GetChildrenHead(); + continue; + } + /* only go to child's sibling */ + view = view->GetNextSibling(); + } + if (--stackCount >= 0) { + view = g_viewStack[stackCount]->GetNextSibling(); + } + } while (stackCount >= 0); + +#if defined __linux__ || defined __LITEOS__ || defined __APPLE__ + pthread_mutex_unlock(&lock_); +#endif +} + +void RootView::OptimizeInvalidView(UIView* curview, UIView* background, List& renderedRects) +{ + if (curview == nullptr) { + return; + } + auto mapEntry = invalidateMap_.find(curview); + if (mapEntry == invalidateMap_.end()) { + return; + } + + Rect& invalidRect = mapEntry->second.Front(); + /* Transparent views should draw from background */ + if (((curview->GetStyleConst().bgOpa_ != OPA_OPAQUE) || (curview->GetOpaScale() != OPA_OPAQUE) || + (!curview->IsTransInvalid())) && + (curview != this)) { + AddInvalidateRect(invalidRect, background); + invalidateMap_.erase(mapEntry); + return; + } + + /* Remove the rendered parts and split the origin rect into splitInvalidRects + * For performance reason, split numbers are strictly restrained. + */ + Vector splitInvalidRects(MAX_SPLIT_NUM << 1); + Rect invalidRectCopy(invalidRect); + /* Using forward order because entries at the front are closer to the current view and have larger Size */ + for (auto iter = renderedRects.Begin(); iter != renderedRects.End(); iter = iter->next_) { + for (int8_t i = 0; i < mapEntry->second.Size(); i++) { + DivideInvalidateRect(iter->data_, mapEntry->second[i], splitInvalidRects); + } + mapEntry->second.Swap(splitInvalidRects); + splitInvalidRects.Clear(); + } + + /* Add new opaque rects */ + Rect preDrawRect(invalidRectCopy); + if (!curview->OnPreDraw(preDrawRect)) { + AddInvalidateRect(invalidRectCopy, background); + } + AddRenderedRects(preDrawRect, renderedRects, renderedRects.Begin()); +} + +void RootView::OptimizeInvalidMap() +{ + UIView* curview = this; + int16_t stackCount = 0; + int16_t opaStackCount = 0; + UIView* background[VIEW_STACK_DEPTH]; + bool flags[VIEW_STACK_DEPTH]; // indicate whether stack go back from child + List renderedRects; // Record rendered areas to avoid rerendering + + do { + /* push stack */ + if (curview != nullptr) { + if (stackCount >= VIEW_STACK_DEPTH) { + return; + } + g_viewStack[stackCount] = curview; + flags[stackCount++] = false; + curview = curview->GetNextSibling(); + continue; + } + + curview = g_viewStack[--stackCount]; + Rect rect(curview->GetRect()); + if (!curview->IsVisible() || !IntersectScreenRect(rect)) { + curview = nullptr; + continue; + } + if (!flags[stackCount]) { // Back from sibling + if (curview->IsViewGroup()) { + /* Set background/topview */ + if (((curview->GetStyleConst().bgOpa_ == OPA_OPAQUE) && (curview->GetOpaScale() == OPA_OPAQUE) && + curview->IsTransInvalid()) || + (curview == this)) { + background[opaStackCount] = curview; + } else { + background[opaStackCount] = background[opaStackCount - 1]; + } + ++opaStackCount; + if (opaStackCount >= VIEW_STACK_DEPTH) { + return; + } + flags[stackCount++] = true; + curview = static_cast(curview)->GetChildrenHead(); + continue; + } + } else { // Back from child + opaStackCount--; + } + OptimizeInvalidView(curview, background[opaStackCount - 1], renderedRects); + curview = nullptr; + } while (stackCount > 0); +} + +void RootView::DrawInvalidMap(const Rect& buffRect) +{ + OptimizeInvalidMap(); + Rect rect; + for (auto& viewEntry : invalidateMap_) { + Vector& viewRenderRect = viewEntry.second; + for (uint16_t i = 0; i < viewRenderRect.Size(); i++) { + rect.Intersect(viewRenderRect[i], buffRect); + DrawTop(viewEntry.first, rect); + } + } +} +#endif + +void RootView::AddInvalidateRect(Rect& rect, UIView* view) +{ + Rect commonRect(rect); + if (IntersectScreenRect(commonRect)) { +#if LOCAL_RENDER + Vector& invalidRects = invalidateMap_[view]; + if (invalidRects.IsEmpty()) { + invalidRects.PushBack(commonRect); + } else { + invalidRects[0].Join(invalidRects[0], commonRect); + } +#else + invalidRect_.Join(invalidRect_, commonRect); + renderFlag_ = true; +#endif + } +} + +void RootView::AddInvalidateRectWithLock(Rect& rect, UIView* view) +{ +#if defined __linux__ || defined __LITEOS__ || defined __APPLE__ + pthread_mutex_lock(&lock_); +#endif + + AddInvalidateRect(rect, view); + +#if defined __linux__ || defined __LITEOS__ || defined __APPLE__ + pthread_mutex_unlock(&lock_); +#endif +} + +void RootView::Measure() +{ +#if LOCAL_RENDER + if (!invalidateMap_.empty()) { + MeasureView(childrenHead_); + } +#else + if (renderFlag_) { + MeasureView(childrenHead_); + } +#endif +} + +void RootView::MeasureView(UIView* view) +{ + int16_t stackCount = 0; + UIView* curView = view; + while (stackCount >= 0) { + while (curView != nullptr) { + if (curView->IsVisible()) { + curView->ReMeasure(); + if (curView->IsViewGroup() && stackCount < COMPONENT_NESTING_DEPTH) { + g_viewStack[stackCount++] = curView; + curView = static_cast(curView)->GetChildrenHead(); + continue; + } + } + curView = curView->GetNextSibling(); + } + if (--stackCount >= 0) { + curView = (g_viewStack[stackCount])->GetNextSibling(); + } + } +} + +void RootView::Render() +{ +#if defined __linux__ || defined __LITEOS__ || defined __APPLE__ + pthread_mutex_lock(&lock_); +#endif + +#if LOCAL_RENDER + if (!invalidateMap_.empty()) { + RenderManager::RenderRect(GetRect(), this); + invalidateMap_.clear(); +#else + if (renderFlag_) { + RenderManager::RenderRect(invalidRect_, this); + invalidRect_ = {0, 0, 0, 0}; + renderFlag_ = false; +#endif + +#if ENABLE_WINDOW + if (boundWindow_) { + boundWindow_->Flush(); + boundWindow_->Update(); + } +#endif + ScreenDeviceProxy::GetInstance()->OnRenderFinish(); + } + +#if defined __linux__ || defined __LITEOS__ || defined __APPLE__ + pthread_mutex_unlock(&lock_); +#endif +} + +void RootView::DrawTop(UIView* view, const Rect& rect) +{ + if (view == nullptr) { + return; + } + + int16_t stackCount = 0; + UIView* par = view->GetParent(); + if (par == nullptr) { + par = view; + } + UIView* curView = view; + UIView* transViewGroup = nullptr; + Rect curViewRect; + Rect mask = rect; + Rect OrigRect; + Rect RelativeRect; + while (par != nullptr) { + if (curView != nullptr) { + if (curView->IsVisible()) { + curViewRect = curView->GetMaskedRect(); + if (curViewRect.Intersect(curViewRect, mask) || enableAnimator_) { + if ((curView->GetViewType() != UI_IMAGE_VIEW) && (curView->GetViewType() != UI_TEXTURE_MAPPER) && + !curView->IsTransInvalid() && !enableAnimator_) { + OrigRect = curView->GetOrigRect(); + RelativeRect = curView->GetRelativeRect(); + curView->GetTransformMap().SetInvalid(true); + curView->SetPosition(RelativeRect.GetX() - OrigRect.GetX(), + RelativeRect.GetY() - OrigRect.GetY()); + ScreenDeviceProxy::GetInstance()->EnableAnimatorBuffer(true); + ScreenDeviceProxy::GetInstance()->SetAnimatorRect(OrigRect); + ScreenDeviceProxy::GetInstance()->SetAnimatorTransMap(curView->GetTransformMap()); + enableAnimator_ = true; + } + if (enableAnimator_) { + Rect invalidatedArea; + invalidatedArea.SetWidth(ScreenDeviceProxy::GetInstance()->GetScreenWidth()); + invalidatedArea.SetHeight(ScreenDeviceProxy::GetInstance()->GetScreenHeight()); + curView->OnDraw(invalidatedArea); + } else { + curView->OnDraw(curViewRect); + } + + if ((curView->IsViewGroup()) && (stackCount < COMPONENT_NESTING_DEPTH)) { + if (enableAnimator_ && (transViewGroup == nullptr)) { + transViewGroup = curView; + } + par = curView; + g_viewStack[stackCount] = curView; + g_maskStack[stackCount] = mask; + stackCount++; + curView = static_cast(curView)->GetChildrenHead(); + mask = par->GetContentRect(); + mask.Intersect(mask, curViewRect); + continue; + } + curView->OnPostDraw(curViewRect); + if (enableAnimator_ && (transViewGroup == nullptr)) { + ScreenDeviceProxy::GetInstance()->EnableAnimatorBuffer(false); + ScreenDeviceProxy::GetInstance()->DrawAnimatorBuffer(mask); + curView->GetTransformMap().SetInvalid(false); + enableAnimator_ = false; + curView->SetPosition(RelativeRect.GetX(), RelativeRect.GetY()); + } + } + } + curView = curView->GetNextSibling(); + continue; + } + if (--stackCount >= 0) { + curViewRect = par->GetMaskedRect(); + mask = g_maskStack[stackCount]; + if (curViewRect.Intersect(curViewRect, g_maskStack[stackCount])) { + par->OnPostDraw(curViewRect); + } + if (enableAnimator_ && transViewGroup == g_viewStack[stackCount]) { + ScreenDeviceProxy::GetInstance()->EnableAnimatorBuffer(false); + ScreenDeviceProxy::GetInstance()->DrawAnimatorBuffer(mask); + transViewGroup->GetTransformMap().SetInvalid(false); + enableAnimator_ = false; + transViewGroup->SetPosition(RelativeRect.GetX(), RelativeRect.GetY()); + transViewGroup = nullptr; + } + curView = g_viewStack[stackCount]->GetNextSibling(); + par = par->GetParent(); + continue; + } + stackCount = 0; + curView = par->GetNextSibling(); + par = par->GetParent(); + } +} + +UIView* RootView::GetTopUIView(const Rect& rect) +{ + int16_t stackCount = 0; + UIView* currentView = this; + UIView* topView = currentView; + Rect copyRect(rect); + while (stackCount >= 0) { + while (currentView != nullptr) { + if (currentView->GetOrigRect().IsContains(rect) && currentView->IsVisible()) { + if (currentView->GetStyleConst().bgOpa_ == OPA_OPAQUE && currentView->OnPreDraw(copyRect) && + currentView->GetOpaScale() == OPA_OPAQUE) { + topView = currentView; + } + if (currentView->IsViewGroup() && stackCount < COMPONENT_NESTING_DEPTH) { + g_viewStack[stackCount++] = currentView; + currentView = static_cast(currentView)->GetChildrenHead(); + continue; + } + } + currentView = currentView->GetNextSibling(); + } + if (--stackCount >= 0) { + currentView = (g_viewStack[stackCount])->GetNextSibling(); + } + } + return topView; +} + +bool RootView::FindSubView(const UIView& parentView, const UIView* subView) +{ + const UIView* root = &parentView; + if (root == subView) { + return true; + } else if (!root->IsViewGroup() || (subView == nullptr)) { + return false; + } + + UIView* currentView = static_cast(root)->GetChildrenHead(); + const UIView* parent = root; + int8_t deep = 1; + while (deep > 0) { + if (currentView == subView) { + return true; + } + if (currentView == nullptr) { + currentView = parent->GetNextSibling(); + parent = parent->GetParent(); + deep--; + } else if (currentView->IsViewGroup()) { + parent = currentView; + currentView = static_cast(currentView)->GetChildrenHead(); + deep++; + } else { + currentView = currentView->GetNextSibling(); + } + } + return false; +} +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/components/text_adapter.cpp b/frameworks/components/text_adapter.cpp new file mode 100755 index 0000000..3df75ff --- /dev/null +++ b/frameworks/components/text_adapter.cpp @@ -0,0 +1,229 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "components/text_adapter.h" +#include +#include "securec.h" + +namespace OHOS { +bool TextFormatter::Format(int16_t value, char* outText, uint16_t textLen) +{ + if (sprintf_s(outText, textLen, "%d", value) < 0) { + return false; + } + return true; +} + +TextAdapter::TextAdapter() + : dataMode_(DYNAMIC_TEXT_MODE), + fontName_(nullptr), + fontSize_(0), + width_(0), + height_(0), + direct_(UITextLanguageDirect::TEXT_DIRECT_LTR), + lineBreakMode_(UILabel::LINE_BREAK_ADAPT), + integerTextStart_(0), + integerTextEnd_(0), + clickListener_(nullptr), + formatter_(nullptr) +{ + style_ = StyleDefault::GetBackgroundTransparentStyle(); + fontId_ = style_.font_; +} + +TextAdapter::~TextAdapter() +{ + ClearDynamicText(); + if (fontName_ != nullptr) { + UIFree(fontName_); + fontName_ = nullptr; + } +} + +void TextAdapter::SetFont(const char* name, uint8_t size) +{ + Text::SetFont(name, size, fontName_, fontSize_); +} + +UIView* TextAdapter::GetView(UIView* inView, int16_t index) +{ + UILabel* newView = GetTextView(inView, index); + if (newView == nullptr) { + return nullptr; + } + newView->SetLineBreakMode(lineBreakMode_); + newView->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); + if (width_) { + newView->SetWidth(width_); + } + if (height_) { + newView->SetHeight(height_); + } + newView->SetViewIndex(index); + newView->UIView::SetStyle(style_); + newView->GetHeight(); + if (clickListener_) { + newView->SetOnClickListener(clickListener_); + newView->SetTouchable(true); + } + return newView; +} + +UILabel* TextAdapter::GetTextView(UIView* inView, int16_t index) +{ + switch (dataMode_) { + case DYNAMIC_TEXT_MODE: + return GetDynamicText(inView, index); + case CONTINUOUS_INTEGER_MODE: + return GetIntegerText(inView, index); + default: + return nullptr; + } +} + +UILabel* TextAdapter::GetDynamicText(UIView* inView, int16_t index) +{ + if (dynamicText_.IsEmpty() || (index > dynamicText_.Size() - 1) || (index < 0)) { + return nullptr; + } + + ListNode* node = dynamicText_.Begin(); + for (int16_t i = 0; i < index; i++) { + node = node->next_; + } + UILabel* newView = nullptr; + if (inView == nullptr) { + newView = new UILabel(); + } else { + newView = static_cast(inView); + } + + if (newView != nullptr) { + newView->SetText(node->data_); + if (fontName_ == nullptr) { + newView->SetFontId(fontId_); + } else { + newView->SetFont(fontName_, fontSize_); + } + newView->SetDirect(direct_); + } + return newView; +} + +UILabel* TextAdapter::GetIntegerText(UIView* inView, int16_t index) +{ + if ((index < 0) || ((integerTextEnd_ - integerTextStart_) < index)) { + return nullptr; + } + UILabel* newView = nullptr; + if (inView == nullptr) { + newView = new UILabel(); + } else { + newView = static_cast(inView); + } + + if (newView != nullptr) { + char buf[BUF_LEN] = {0}; + if (formatter_ != nullptr) { + if (!formatter_->Format(integerTextStart_ + index, buf, BUF_LEN)) { + if (inView == nullptr) { + delete newView; + newView = nullptr; + } + return nullptr; + } + } else { + if (sprintf_s(buf, sizeof(buf), "%02d", integerTextStart_ + index) < 0) { + if (inView == nullptr) { + delete newView; + newView = nullptr; + } + return nullptr; + } + } + + buf[BUF_LEN - 1] = '\0'; + newView->SetText(buf); + if (fontName_ == nullptr) { + newView->SetFontId(fontId_); + } else { + newView->SetFont(fontName_, fontSize_); + } + newView->SetDirect(direct_); + } + return newView; +} + +void TextAdapter::ClearDynamicText() +{ + ListNode* node = dynamicText_.Begin(); + while (node != dynamicText_.End()) { + if (node->data_) { + UIFree(reinterpret_cast(const_cast(node->data_))); + node->data_ = nullptr; + } + node = node->next_; + } + dynamicText_.Clear(); +} + +void TextAdapter::SetData(List* data) +{ + if (data == nullptr) { + return; + } + if (!dynamicText_.IsEmpty()) { + ClearDynamicText(); + } + ListNode* node = data->Begin(); + while (node != data->End()) { + uint32_t len = strlen(node->data_); + char* stringData = static_cast(UIMalloc(len + 1)); + if (stringData == nullptr) { + return; + } + if (memcpy_s(stringData, len + 1, node->data_, len) != EOK) { + UIFree(reinterpret_cast(stringData)); + stringData = nullptr; + return; + } + stringData[len] = '\0'; + dynamicText_.PushBack(stringData); + node = node->next_; + } + dataMode_ = DYNAMIC_TEXT_MODE; +} + +void TextAdapter::SetData(int16_t start, int16_t end) +{ + if (start <= end) { + integerTextStart_ = start; + integerTextEnd_ = end; + dataMode_ = CONTINUOUS_INTEGER_MODE; + } +} + +uint16_t TextAdapter::GetCount() +{ + switch (dataMode_) { + case DYNAMIC_TEXT_MODE: + return dynamicText_.Size(); + case CONTINUOUS_INTEGER_MODE: + return (integerTextStart_ <= integerTextEnd_) ? (integerTextEnd_ - integerTextStart_ + 1) : 0; + default: + return 0; + } +} +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/components/ui_abstract_clock.cpp b/frameworks/components/ui_abstract_clock.cpp new file mode 100755 index 0000000..fa053da --- /dev/null +++ b/frameworks/components/ui_abstract_clock.cpp @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "components/ui_abstract_clock.h" + +namespace OHOS { +void UIAbstractClock::SetTime24Hour(uint8_t hour, uint8_t minute, uint8_t second) +{ + currentHour_ = hour % ONE_DAY_IN_HOUR; + currentMinute_ = minute % ONE_HOUR_IN_MINUTE; + currentSecond_ = second % ONE_MINUTE_IN_SECOND; + UpdateClock(false); +} + +void UIAbstractClock::SetTime12Hour(uint8_t hour, uint8_t minute, uint8_t second, bool am) +{ + SetTime24Hour((hour % HALF_DAY_IN_HOUR) + (am ? 0 : HALF_DAY_IN_HOUR), minute, second); +} + +void UIAbstractClock::IncOneSecond() +{ + currentSecond_++; + currentMinute_ += currentSecond_ / ONE_MINUTE_IN_SECOND; + currentSecond_ = currentSecond_ % ONE_MINUTE_IN_SECOND; + + currentHour_ += currentMinute_ / ONE_HOUR_IN_MINUTE; + currentMinute_ = currentMinute_ % ONE_HOUR_IN_MINUTE; + currentHour_ = currentHour_ % ONE_DAY_IN_HOUR; + + UpdateClock(false); +} + +void UIAbstractClock::SetWorkMode(WorkMode newMode) +{ + if (mode_ != newMode) { + mode_ = newMode; + Invalidate(); + } +} + +void UIAbstractClock::UpdateClock(bool clockInit) +{ + Invalidate(); +} +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/components/ui_abstract_progress.cpp b/frameworks/components/ui_abstract_progress.cpp new file mode 100755 index 0000000..8f9e62c --- /dev/null +++ b/frameworks/components/ui_abstract_progress.cpp @@ -0,0 +1,230 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "components/ui_abstract_progress.h" +#include "common/image.h" +#include "draw/draw_utils.h" +#include "graphic_log.h" +#include "imgdecode/cache_manager.h" +#include "themes/theme_manager.h" + +namespace OHOS { +UIAbstractProgress::UIAbstractProgress() + : enableBackground_(true), + backgroundStyleAllocFlag_(false), + foregroundStyleAllocFlag_(false), + backgroundImage_(nullptr), + foregroundImage_(nullptr), + rangeMax_(MAX_PERCENT_VALUE), + rangeMin_(MIN_PERCENT_VALUE), + curValue_(0), + step_(1), + lastValue_(0) +{ + style_ = &(StyleDefault::GetBackgroundTransparentStyle()); + Theme* theme = ThemeManager::GetInstance().GetCurrent(); + if (theme != nullptr) { + backgroundStyle_ = &(theme->GetProgressBackgroundStyle()); + foregroundStyle_ = &(theme->GetProgressForegroundStyle()); + } else { + backgroundStyle_ = &(StyleDefault::GetProgressBackgroundStyle()); + foregroundStyle_ = &(StyleDefault::GetProgressForegroundStyle()); + } +} + +UIAbstractProgress::~UIAbstractProgress() +{ + if (backgroundImage_ != nullptr) { + delete backgroundImage_; + backgroundImage_ = nullptr; + } + + if (foregroundImage_ != nullptr) { + delete foregroundImage_; + foregroundImage_ = nullptr; + } + + if (backgroundStyleAllocFlag_) { + delete backgroundStyle_; + backgroundStyle_ = nullptr; + backgroundStyleAllocFlag_ = false; + } + + if (foregroundStyleAllocFlag_) { + delete foregroundStyle_; + foregroundStyle_ = nullptr; + foregroundStyleAllocFlag_ = false; + } +} + +void UIAbstractProgress::SetRange(int32_t rangeMax, int32_t rangeMin) +{ + if ((rangeMax_ == rangeMax) && (rangeMin_ == rangeMin)) { + return; + } + + if (rangeMax >= rangeMin) { + rangeMax_ = rangeMax; + rangeMin_ = rangeMin; + lastValue_ = rangeMin; + SetValue(curValue_); + } else { + GRAPHIC_LOGW("UIAbstractProgress::SetRange rangeMax less than rangeMin !\n"); + } +}; + +void UIAbstractProgress::SetValue(int32_t value) +{ + if (value < rangeMin_) { + curValue_ = rangeMin_; + } else if (value > rangeMax_) { + curValue_ = rangeMax_; + } else { + curValue_ = value; + } + + if ((curValue_ != lastValue_) && + ((curValue_ == rangeMin_) || (curValue_ == rangeMax_) || + (MATH_ABS(curValue_ - lastValue_) >= static_cast(step_)))) { + Invalidate(); + lastValue_ = curValue_; + } +} + +int16_t UIAbstractProgress::GetCurrentPos(int16_t distance) const +{ + uint32_t delta = lastValue_ - rangeMin_; + uint32_t rangeSize = GetRangeSize(); + if (rangeSize == 0) { + return distance; + } + int16_t result = static_cast(distance) * delta / rangeSize; + return result; +} + +uint32_t UIAbstractProgress::GetRangeSize() const +{ + return (rangeMax_ < rangeMin_) ? 0 : (rangeMax_ - rangeMin_); +} + +void UIAbstractProgress::SetImage(const char* foregroundImage, const char* backgroundImage) +{ + if (!InitImage()) { + return; + } + backgroundImage_->SetSrc(backgroundImage); + foregroundImage_->SetSrc(foregroundImage); +} + +void UIAbstractProgress::SetImage(const ImageInfo* foregroundImage, const ImageInfo* backgroundImage) +{ + if (!InitImage()) { + return; + } + backgroundImage_->SetSrc(backgroundImage); + foregroundImage_->SetSrc(foregroundImage); +} + +void UIAbstractProgress::SetBackgroundStyle(const Style& style) +{ + if (!backgroundStyleAllocFlag_) { + backgroundStyle_ = new Style(); + if (backgroundStyle_ == nullptr) { + GRAPHIC_LOGE("new Style1 fail"); + return; + } + backgroundStyleAllocFlag_ = true; + } + *backgroundStyle_ = style; +} + +void UIAbstractProgress::SetBackgroundStyle(uint8_t key, int64_t value) +{ + if (!backgroundStyleAllocFlag_) { + backgroundStyle_ = new Style(*backgroundStyle_); + if (backgroundStyle_ == nullptr) { + GRAPHIC_LOGE("new Style1 fail"); + return; + } + backgroundStyleAllocFlag_ = true; + } + backgroundStyle_->SetStyle(key, value); +} + +const Style& UIAbstractProgress::GetBackgroundStyle() const +{ + return *backgroundStyle_; +} + +int64_t UIAbstractProgress::GetBackgroundStyle(uint8_t key) const +{ + return backgroundStyle_->GetStyle(key); +} + +void UIAbstractProgress::SetForegroundStyle(const Style& style) +{ + if (!foregroundStyleAllocFlag_) { + foregroundStyle_ = new Style(); + if (foregroundStyle_ == nullptr) { + GRAPHIC_LOGE("new Style1 fail"); + return; + } + foregroundStyleAllocFlag_ = true; + } + *foregroundStyle_ = style; +} + +void UIAbstractProgress::SetForegroundStyle(uint8_t key, int64_t value) +{ + if (!foregroundStyleAllocFlag_) { + foregroundStyle_ = new Style(*foregroundStyle_); + if (foregroundStyle_ == nullptr) { + GRAPHIC_LOGE("new Style1 fail"); + return; + } + foregroundStyleAllocFlag_ = true; + } + foregroundStyle_->SetStyle(key, value); +} + +const Style& UIAbstractProgress::GetForegroundStyle() const +{ + return *foregroundStyle_; +} + +int64_t UIAbstractProgress::GetForegroundStyle(uint8_t key) const +{ + return foregroundStyle_->GetStyle(key); +} + +bool UIAbstractProgress::InitImage() +{ + if (backgroundImage_ == nullptr) { + backgroundImage_ = new Image(); + if (backgroundImage_ == nullptr) { + GRAPHIC_LOGE("new Image fail"); + return false; + } + } + if (foregroundImage_ == nullptr) { + foregroundImage_ = new Image(); + if (foregroundImage_ == nullptr) { + GRAPHIC_LOGE("new Image fail"); + return false; + } + } + return true; +} +} // namespace OHOS diff --git a/frameworks/components/ui_abstract_scroll.cpp b/frameworks/components/ui_abstract_scroll.cpp new file mode 100755 index 0000000..2c6d90a --- /dev/null +++ b/frameworks/components/ui_abstract_scroll.cpp @@ -0,0 +1,182 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "components/ui_abstract_scroll.h" + +namespace OHOS { +UIAbstractScroll::UIAbstractScroll() + : scrollBlankSize_(0), + reboundSize_(0), + maxScrollDistance_(0), + lastDeltaY_{0}, + dragAccCoefficient_(DRAG_ACC_FACTOR), + swipeAccCoefficient_(0), + direction_(VERTICAL), + deltaYIndex_(0), + reserve_(0), + throwDrag_(false), + easingFunc_(EasingEquation::CubicEaseOut), + scrollAnimator_(&animatorCallback_, this, 0, true) +{ +#if ENABLE_ROTATE_INPUT + rotateFactor_ = 1; + rotateThreshold_ = 1; +#endif + isViewGroup_ = true; + touchable_ = true; + draggable_ = true; + dragParentInstead_ = false; + AnimatorManager::GetInstance()->Add(&scrollAnimator_); +} + +UIAbstractScroll::~UIAbstractScroll() +{ + scrollAnimator_.Stop(); + AnimatorManager::GetInstance()->Remove(&scrollAnimator_); +} + +void UIAbstractScroll::MoveChildByOffset(int16_t offsetX, int16_t offsetY) +{ + if ((offsetX == 0) && (offsetY == 0)) { + return; + } + UIView* view = GetChildrenHead(); + int16_t x; + int16_t y; + while (view != nullptr) { + x = view->GetX() + offsetX; + y = view->GetY() + offsetY; + view->SetPosition(x, y); + view = view->GetNextSibling(); + } + Invalidate(); +} + +int16_t UIAbstractScroll::GetMaxDeltaY() const +{ + int16_t result = 0; + for (int16_t i = 0; i < MAX_DELTA_Y_SIZE; i++) { + if (result < MATH_ABS(lastDeltaY_[i])) { + result = MATH_ABS(lastDeltaY_[i]); + } + } + return result; +} + +void UIAbstractScroll::StopAnimator() +{ + scrollAnimator_.Stop(); + animatorCallback_.RsetCallback(); + isDragging_ = false; +} + +bool UIAbstractScroll::DragThrowAnimator(Point currentPos, Point lastPos) +{ + if (!throwDrag_ && (reboundSize_ == 0)) { + return false; + } + int16_t dragDistanceX = 0; + int16_t dragDistanceY = 0; + if (throwDrag_) { + CalculateDragDistance(currentPos, lastPos, dragDistanceX, dragDistanceY); + } + if (reboundSize_ != 0) { + CalculateReboundDistance(dragDistanceX, dragDistanceY); + } + StartAnimator(dragDistanceX, dragDistanceY); + return true; +} + +void UIAbstractScroll::StartAnimator(int16_t dragDistanceX, int16_t dragDistanceY) +{ + int16_t dragTimes = MATH_MAX(MATH_ABS(dragDistanceX), MATH_ABS(dragDistanceY)) / DRAG_TIMES_COEFFICIENT; + if (dragTimes < MIN_DRAG_TIMES) { + dragTimes = MIN_DRAG_TIMES; + } + animatorCallback_.SetDragStartValue(0, 0); + animatorCallback_.SetDragEndValue(dragDistanceX, dragDistanceY); + animatorCallback_.SetDragTimes(dragTimes * DRAG_ACC_FACTOR / GetDragACCLevel()); + scrollAnimator_.Start(); +} + +void UIAbstractScroll::CalculateDragDistance(Point currentPos, + Point lastPos, + int16_t& dragDistanceX, + int16_t& dragDistanceY) +{ + if ((direction_ == VERTICAL) || (direction_ == HORIZONTAL_AND_VERTICAL)) { + dragDistanceY = (currentPos.y - lastPos.y) * DRAG_DISTANCE_COEFFICIENT; + if (dragDistanceY > 0) { + dragDistanceY += GetMaxDeltaY() * GetSwipeACCLevel() / DRAG_ACC_FACTOR; + } else { + dragDistanceY -= GetMaxDeltaY() * GetSwipeACCLevel() / DRAG_ACC_FACTOR; + } + } + + if ((direction_ == HORIZONTAL) || (direction_ == HORIZONTAL_AND_VERTICAL)) { + dragDistanceX = (currentPos.x - lastPos.x) * DRAG_DISTANCE_COEFFICIENT; + } + + if (maxScrollDistance_ != 0) { + if (MATH_ABS(dragDistanceY) > maxScrollDistance_) { + int16_t calculatedValue = (dragDistanceY > 0) ? 1 : -1; + dragDistanceY = calculatedValue * maxScrollDistance_; + } + if (MATH_ABS(dragDistanceX) > maxScrollDistance_) { + int16_t calculatedValue = (dragDistanceX > 0) ? 1 : -1; + dragDistanceX = calculatedValue * maxScrollDistance_; + } + } +} + +void UIAbstractScroll::ListAnimatorCallback::Callback(UIView* view) +{ + if (view == nullptr) { + return; + } + curtTime_++; + + UIAbstractScroll* scrollView = static_cast(view); + scrollView->isDragging_ = true; + + if (curtTime_ <= dragTimes_) { + bool needStopX = false; + bool needStopY = false; + if (startValueY_ != endValueY_) { + int16_t actY = scrollView->easingFunc_(startValueY_, endValueY_, curtTime_, dragTimes_); + if (!scrollView->DragYInner(actY - previousValueY_)) { + needStopY = true; + } + previousValueY_ = actY; + } else { + needStopY = true; + } + if (startValueX_ != endValueX_) { + int16_t actX = scrollView->easingFunc_(startValueX_, endValueX_, curtTime_, dragTimes_); + if (!scrollView->DragXInner(actX - previousValueX_)) { + needStopX = true; + } + previousValueX_ = actX; + } else { + needStopX = true; + } + if (needStopX && needStopY) { + scrollView->StopAnimator(); + } + } else { + scrollView->StopAnimator(); + } +} +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/components/ui_analog_clock.cpp b/frameworks/components/ui_analog_clock.cpp new file mode 100755 index 0000000..3780a87 --- /dev/null +++ b/frameworks/components/ui_analog_clock.cpp @@ -0,0 +1,336 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "components/ui_analog_clock.h" +#include "components/ui_image_view.h" +#include "draw/draw_image.h" +#include "draw/draw_line.h" +#include "draw/draw_rect.h" +#include "graphic_log.h" +#include "imgdecode/cache_manager.h" +#include "style.h" +#include "themes/theme.h" + +namespace OHOS { +UIAnalogClock::UIAnalogClock() +{ + touchable_ = true; +} + +void UIAnalogClock::SetHandImage(HandType type, const UIImageView& img, Point position, Point center) +{ + Hand *hand = nullptr; + if (type == HandType::HOUR_HAND) { + hand = &hourHand_; + } else if (type == HandType::MINUTE_HAND) { + hand = &minuteHand_; + } else { + hand = &secondHand_; + } + + hand->center_ = center; + hand->position_ = position; + hand->initAngle_ = 0; + hand->preAngle_ = 0; + hand->nextAngle_ = 0; + hand->drawtype_ = DrawType::DRAW_IMAGE; + + if (img.GetSrcType() == IMG_SRC_FILE) { + CacheEntry entry; + RetCode ret = CacheManager::GetInstance().Open(img.GetPath(), *style_, entry); + if (ret != RetCode::OK) { + return; + } + hand->imageInfo_ = entry.GetImageInfo(); + } else { + hand->imageInfo_ = *(img.GetImageInfo()); + } +} + +void UIAnalogClock::SetHandLine(HandType type, Point position, Point center, ColorType color, + uint16_t width, uint16_t height, OpacityType opacity) +{ + Hand* hand = nullptr; + if (type == HandType::HOUR_HAND) { + hand = &hourHand_; + } else if (type == HandType::MINUTE_HAND) { + hand = &minuteHand_; + } else { + hand = &secondHand_; + } + + hand->color_ = color; + hand->height_ = height; + hand->width_ = width; + hand->position_ = position; + hand->center_ = center; + hand->opacity_ = opacity; + hand->initAngle_ = 0; + hand->preAngle_ = 0; + hand->nextAngle_ = 0; + hand->drawtype_ = DrawType::DRAW_LINE; +} + +Point UIAnalogClock::GetHandRotateCenter(HandType type) const +{ + if (type == HandType::HOUR_HAND) { + return hourHand_.center_; + } else if (type == HandType::MINUTE_HAND) { + return minuteHand_.center_; + } else { + return secondHand_.center_; + } +} + +Point UIAnalogClock::GetHandPosition(HandType type) const +{ + if (type == HandType::HOUR_HAND) { + return hourHand_.position_; + } else if (type == HandType::MINUTE_HAND) { + return minuteHand_.position_; + } else { + return secondHand_.position_; + } +} + +uint16_t UIAnalogClock::GetHandInitAngle(HandType type) const +{ + if (type == HandType::HOUR_HAND) { + return hourHand_.initAngle_; + } else if (type == HandType::MINUTE_HAND) { + return minuteHand_.initAngle_; + } else { + return secondHand_.initAngle_; + } +} + +uint16_t UIAnalogClock::GetHandCurrentAngle(HandType type) const +{ + if (type == HandType::HOUR_HAND) { + return hourHand_.nextAngle_; + } else if (type == HandType::MINUTE_HAND) { + return minuteHand_.nextAngle_; + } else { + return secondHand_.nextAngle_; + } +} + +void UIAnalogClock::SetInitTime24Hour(uint8_t hour, uint8_t minute, uint8_t second) +{ + currentHour_ = hour % ONE_DAY_IN_HOUR; + currentMinute_ = minute % ONE_HOUR_IN_MINUTE; + currentSecond_ = second % ONE_MINUTE_IN_SECOND; + + hourHand_.initAngle_ = ConvertHandValueToAngle(currentHour_, + HALF_DAY_IN_HOUR, currentMinute_, ONE_HOUR_IN_MINUTE); + hourHand_.preAngle_ = hourHand_.initAngle_; + hourHand_.nextAngle_ = hourHand_.initAngle_; + + minuteHand_.initAngle_ = ConvertHandValueToAngle(currentMinute_, + ONE_HOUR_IN_MINUTE, currentSecond_, ONE_MINUTE_IN_SECOND); + minuteHand_.preAngle_ = minuteHand_.initAngle_; + minuteHand_.nextAngle_ = minuteHand_.initAngle_; + + secondHand_.initAngle_ = ConvertHandValueToAngle(currentSecond_, ONE_MINUTE_IN_SECOND); + secondHand_.preAngle_ = secondHand_.initAngle_; + secondHand_.nextAngle_ = secondHand_.initAngle_; + + UpdateClock(true); +} + +void UIAnalogClock::SetInitTime12Hour(uint8_t hour, uint8_t minute, uint8_t second, bool am) +{ + SetInitTime24Hour((hour % HALF_DAY_IN_HOUR) + (am ? 0 : HALF_DAY_IN_HOUR), minute, second); +} + +uint16_t UIAnalogClock::ConvertHandValueToAngle(uint8_t handValue, uint8_t range, + uint8_t secondHandValue, uint8_t ratio) const +{ + if ((range == 0) || (ratio == 0)) { + GRAPHIC_LOGW("UIAnalogClock::ConvertHandValueToAngle Invalid range or ratio\n"); + return 0; + } + /* + * Example: calculate the angle of hour hand + * Assume that the time is 5: 30, then range is 12, radio is 60 + * angle is [(5 * 60 + 30) / (12 * 60)] * 360 + */ + uint32_t degree = (static_cast(handValue) * ratio + secondHandValue); + degree = static_cast(CIRCLE_IN_DEGREE * degree / (static_cast(range) * ratio)); + + return static_cast(degree % CIRCLE_IN_DEGREE); +} + +uint16_t UIAnalogClock::ConvertHandValueToAngle(uint8_t handValue, uint8_t range) const +{ + if (range == 0) { + GRAPHIC_LOGW("UIAnalogClock::ConvertHandValueToAngle Invalid range or ratio\n"); + return 0; + } + /* + * Example: calculate the angle of second hand without millisecond handle + * Assume that the time is 5:30:30, then range is 60 + * angle is (30 / 60) * 360 + */ + return (static_cast(handValue) * CIRCLE_IN_DEGREE / range); +} + +void UIAnalogClock::UpdateClock(bool clockInit) +{ + Invalidate(); + hourHand_.nextAngle_ = ConvertHandValueToAngle(currentHour_, + HALF_DAY_IN_HOUR, currentMinute_, ONE_HOUR_IN_MINUTE); + + minuteHand_.nextAngle_ = ConvertHandValueToAngle(currentMinute_, + ONE_HOUR_IN_MINUTE, currentSecond_, ONE_MINUTE_IN_SECOND); + + secondHand_.nextAngle_ = ConvertHandValueToAngle(currentSecond_, ONE_MINUTE_IN_SECOND); + + Rect rect = GetRect(); + CalculateRedrawArea(rect, hourHand_, clockInit); + CalculateRedrawArea(rect, minuteHand_, clockInit); + if (GetWorkMode() == WorkMode::NORMAL) { + CalculateRedrawArea(rect, secondHand_, clockInit); + } +} + +void UIAnalogClock::OnDraw(const Rect& invalidatedArea) +{ + DrawRect::Draw(GetRect(), invalidatedArea, *style_, opaScale_); +} + +void UIAnalogClock::OnPostDraw(const Rect& invalidatedArea) +{ + Rect current = GetOrigRect(); + DrawHand(current, invalidatedArea, hourHand_); + DrawHand(current, invalidatedArea, minuteHand_); + if (GetWorkMode() == WorkMode::NORMAL) { + DrawHand(current, invalidatedArea, secondHand_); + } +} + +void UIAnalogClock::SetPosition(int16_t x, int16_t y) +{ + UIViewGroup::SetPosition(x, y); + UpdateClock(true); +} + +void UIAnalogClock::SetPosition(int16_t x, int16_t y, int16_t width, int16_t height) +{ + UIViewGroup::SetPosition(x, y, width, height); + UpdateClock(true); +} + +void UIAnalogClock::CalculateRedrawArea(const Rect& current, Hand& hand, bool clockInit) +{ + /* + * Use the current image as an independent rectangular area + * to calculate the coordinate conversion coefficient. + */ + int16_t imgWidth = hand.imageInfo_.header.width; + int16_t imgHeight = hand.imageInfo_.header.height; + + int16_t left = hand.position_.x + current.GetLeft(); + int16_t right = left + imgWidth; + int16_t top = hand.position_.y + current.GetTop(); + int16_t bottom = top + imgHeight; + Rect imgRect(left, top, right, bottom); + TransformMap backwardMap(imgRect); + Vector2 pivot; + pivot.x_ = hand.center_.x; + pivot.y_ = hand.center_.y; + + /* Rotate the specified angle, */ + backwardMap.Rotate(hand.nextAngle_ - hand.initAngle_, pivot); + Rect redraw = hand.target_; + hand.target_ = backwardMap.GetBoxRect(); + hand.trans_ = backwardMap; + hand.preAngle_ = hand.nextAngle_; + if (!clockInit) { + /* Prevent old images from being residued */ + redraw.Join(redraw, hand.target_); + InvalidateRect(redraw); + } +} + +void UIAnalogClock::DrawHand(const Rect& current, const Rect& invalidatedArea, Hand& hand) +{ + if (hand.drawtype_ == DrawType::DRAW_IMAGE) { + DrawHandImage(current, invalidatedArea, hand); + } else { + DrawHandLine(invalidatedArea, hand); + } +} + +void UIAnalogClock::DrawHandImage(const Rect& current, const Rect& invalidatedArea, Hand& hand) +{ + uint8_t pxSize = DrawUtils::GetPxSizeByColorMode(hand.imageInfo_.header.colorMode); + TransformDataInfo imageTranDataInfo = { + hand.imageInfo_.header, hand.imageInfo_.data, pxSize, + BlurLevel::LEVEL0, TransformAlgorithm::BILINEAR + }; + DrawUtils::GetInstance()->DrawTransform(invalidatedArea, { 0, 0 }, + Color::Black(), opaScale_, hand.trans_, imageTranDataInfo); +} + +void UIAnalogClock::DrawHandLine(const Rect& invalidatedArea, Hand& hand) +{ + float sinma = Sin(hand.nextAngle_); + float cosma = Sin(hand.nextAngle_ + THREE_QUARTER_IN_DEGREE); + int32_t handLength = hand.height_; + Rect rect = GetRect(); + Point start; + Point end; + Point curCenter; + curCenter.x = hand.position_.x + hand.center_.x + rect.GetLeft(); + curCenter.y = hand.position_.y + hand.center_.y + rect.GetTop(); + + int32_t startToCenterLength = hand.center_.y; + + int32_t xPointLength = static_cast(startToCenterLength * sinma); + int32_t yPointLength = static_cast(startToCenterLength * cosma); + + start.x = xPointLength + curCenter.x; + start.y = yPointLength + curCenter.y; + + /* + * @ startToCenterLength: means the length between StartPoint and CenterPoint. + * @ handlength: means the hand height. + * @ xlength: means X-axis length relative to the center point + * @ ylength: means Y-axis length relative to the center point + */ + int32_t xlength = static_cast((startToCenterLength - handLength) * sinma); + int32_t ylength = static_cast((startToCenterLength - handLength) * cosma); + end.x = xlength + curCenter.x; + end.y = ylength + curCenter.y; + + DrawLine::Draw(start, end, invalidatedArea, hand.width_, hand.color_, hand.opacity_); +} + +void UIAnalogClock::SetWorkMode(WorkMode newMode) +{ + WorkMode oldMode = mode_; + + if (oldMode != newMode) { + /* + * After entering the alwayson mode, all child controls are no longer drawn, + * making the simplest analog clock. + */ + isViewGroup_ = (newMode == ALWAYS_ON) ? false : true; + mode_ = newMode; + Invalidate(); + } +} +} // namespace OHOS diff --git a/frameworks/components/ui_arc_label.cpp b/frameworks/components/ui_arc_label.cpp new file mode 100755 index 0000000..c93d148 --- /dev/null +++ b/frameworks/components/ui_arc_label.cpp @@ -0,0 +1,219 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "components/ui_arc_label.h" +#include "common/typed_text.h" +#include "draw/draw_label.h" +#include "draw/draw_rect.h" +#include "font/ui_font.h" +#include "themes/theme_manager.h" + +namespace OHOS { +UIArcLabel::UIArcLabel() + : arcLabelText_(nullptr), + needRefresh_(false), + textSize_({0, 0}), + radius_(0), + startAngle_(0), + endAngle_(0), + arcCenter_({0, 0}), + orientation_(TextOrientation::INSIDE), + arcTextInfo_{0} +{ + Theme* theme = ThemeManager::GetInstance().GetCurrent(); + style_ = (theme != nullptr) ? &(theme->GetLabelStyle()) : &(StyleDefault::GetLabelStyle()); +} + +UIArcLabel::~UIArcLabel() +{ + if (arcLabelText_ != nullptr) { + delete arcLabelText_; + arcLabelText_ = nullptr; + } +} + +void UIArcLabel::SetStyle(uint8_t key, int64_t value) +{ + UIView::SetStyle(key, value); + RefreshArcLabel(); +} + +void UIArcLabel::SetText(const char* text) +{ + if (text == nullptr) { + return; + } + InitArcLabelText(); + arcLabelText_->SetText(text); + if (arcLabelText_->IsNeedRefresh()) { + RefreshArcLabel(); + } +} + +const char* UIArcLabel::GetText() const +{ + return (arcLabelText_ == nullptr) ? nullptr : arcLabelText_->GetText(); +} + +void UIArcLabel::SetAlign(UITextLanguageAlignment horizontalAlign) +{ + InitArcLabelText(); + arcLabelText_->SetAlign(horizontalAlign, TEXT_ALIGNMENT_TOP); + if (arcLabelText_->IsNeedRefresh()) { + RefreshArcLabel(); + } +} + +UITextLanguageAlignment UIArcLabel::GetHorAlign() +{ + InitArcLabelText(); + return arcLabelText_->GetHorAlign(); +} + +UITextLanguageDirect UIArcLabel::GetDirect() +{ + InitArcLabelText(); + return arcLabelText_->GetDirect(); +} + +void UIArcLabel::SetFontId(uint8_t fontId) +{ + InitArcLabelText(); + arcLabelText_->SetFontId(fontId); + if (arcLabelText_->IsNeedRefresh()) { + RefreshArcLabel(); + } +} + +uint8_t UIArcLabel::GetFontId() +{ + InitArcLabelText(); + return arcLabelText_->GetFontId(); +} + +void UIArcLabel::SetFont(const char* name, uint8_t size) +{ + if (name == nullptr) { + return; + } + InitArcLabelText(); + arcLabelText_->SetFont(name, size); + if (arcLabelText_->IsNeedRefresh()) { + RefreshArcLabel(); + } +} + +void UIArcLabel::OnDraw(const Rect& invalidatedArea) +{ + InitArcLabelText(); + const char* text = arcLabelText_->GetText(); + if ((text == nullptr) || (radius_ == 0)) { + return; + } + Rect trunc = invalidatedArea; + OpacityType opa = GetMixOpaScale(); + DrawRect::Draw(GetRect(), trunc, *style_, opa); + + Rect coords = GetContentRect(); + if (trunc.Intersect(trunc, coords)) { + DrawArcText(trunc, opa); + } +} + +void UIArcLabel::DrawArcText(const Rect& mask, OpacityType opaScale) +{ + Point center; + center.x = arcTextInfo_.arcCenter.x + GetRect().GetX(); + center.y = arcTextInfo_.arcCenter.y + GetRect().GetY(); + InitArcLabelText(); + UIFont::GetInstance()->SetCurrentFontId(arcLabelText_->GetFontId(), arcLabelText_->GetFontSize()); + DrawLabel::DrawArcText(mask, arcLabelText_->GetText(), center, arcLabelText_->GetFontId(), + arcTextInfo_, orientation_, *style_, opaScale); +} + +void UIArcLabel::RefreshArcLabel() +{ + Invalidate(); + if (!needRefresh_) { + needRefresh_ = true; + } +} + +void UIArcLabel::ReMeasure() +{ + if (!needRefresh_) { + return; + } + needRefresh_ = false; + InitArcLabelText(); + UIFont::GetInstance()->SetCurrentFontId(arcLabelText_->GetFontId(), arcLabelText_->GetFontSize()); + + MeasureArcTextInfo(); + Rect textRect = TypedText::GetArcTextRect(arcLabelText_->GetText(), + arcCenter_, + style_->letterSpace_, + orientation_, + arcTextInfo_); + int16_t arcTextWidth = textRect.GetWidth(); + int16_t arcTextHeight = textRect.GetHeight(); + + SetPosition(textRect.GetX(), textRect.GetY()); + Resize(arcTextWidth, arcTextHeight); + arcTextInfo_.arcCenter.x = arcCenter_.x - GetX(); + arcTextInfo_.arcCenter.y = arcCenter_.y - GetY(); + textSize_.x = arcTextWidth; + textSize_.y = arcTextHeight; + Invalidate(); +} + +void UIArcLabel::MeasureArcTextInfo() +{ + const char* text = arcLabelText_->GetText(); + if (text == nullptr) { + return; + } + uint16_t letterHeight = UIFont::GetInstance()->GetHeight(); + arcTextInfo_.radius = ((orientation_ == TextOrientation::INSIDE) ? radius_ : (radius_ - letterHeight)); + if (arcTextInfo_.radius == 0) { + return; + } + + uint16_t arcAngle; + if (startAngle_ < endAngle_) { + arcAngle = endAngle_ - startAngle_; + arcTextInfo_.direct = TEXT_DIRECT_LTR; // Clockwise + arcLabelText_->SetDirect(TEXT_DIRECT_LTR); + } else { + arcAngle = startAngle_ - endAngle_; + arcTextInfo_.direct = TEXT_DIRECT_RTL; // Counterclockwise + arcLabelText_->SetDirect(TEXT_DIRECT_RTL); + } + // calculate max arc length + float maxLength = static_cast((UI_PI * radius_ * arcAngle) / SEMICIRCLE_IN_DEGREE); + arcTextInfo_.lineStart = 0; + arcTextInfo_.lineEnd = TypedText::GetNextLine(&text[arcTextInfo_.lineStart], style_->letterSpace_, maxLength); + arcTextInfo_.startAngle = startAngle_ % CIRCLE_IN_DEGREE; + int16_t actLength = TypedText::GetTextWidth(&text[arcTextInfo_.lineStart], + arcTextInfo_.lineEnd - arcTextInfo_.lineStart, style_->letterSpace_); + if ((arcLabelText_->GetHorAlign() != TEXT_ALIGNMENT_LEFT) && (actLength < maxLength)) { + float gapLength = maxLength - actLength; + if (arcLabelText_->GetHorAlign() == TEXT_ALIGNMENT_CENTER) { + gapLength = gapLength / 2; // 2: half + } + arcTextInfo_.startAngle += TypedText::GetAngleForArcLen(gapLength, letterHeight, arcTextInfo_.radius, + arcTextInfo_.direct, orientation_); + } +} +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/components/ui_axis.cpp b/frameworks/components/ui_axis.cpp new file mode 100755 index 0000000..9193eb8 --- /dev/null +++ b/frameworks/components/ui_axis.cpp @@ -0,0 +1,197 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "components/ui_axis.h" +#include "common/screen.h" +#include "draw/draw_line.h" + +namespace OHOS { +UIAxis::UIAxis() + : maxRange_(0), + minRange_(0), + start_({0, 0}), + end_({0, 0}), + markInterval_(0), + dataPerMark_(0), + dataInterval_(0), + markDataCount_(AXIS_DEFAULT_MARK_INTERVAL), + enableReverse_(false) +{ + SetStyle(STYLE_LINE_WIDTH, 1); + SetStyle(STYLE_LINE_COLOR, Color::White().full); +} + +void UIAxis::SetLineColor(const ColorType& color) +{ + SetStyle(STYLE_LINE_COLOR, color.full); +} + +void UIXAxis::SetMarkNum(uint16_t count) +{ + if ((count == 0) || (count > Screen::GetInstance().GetWidth())) { + return; + } + markDataCount_ = count; + UpdateAxis(); +} + +bool UIXAxis::SetDataRange(uint16_t min, uint16_t max) +{ + if (max <= min) { + return false; + } + maxRange_ = max; + minRange_ = min; + return UpdateAxis(); +} + +void UIXAxis::UpdateAxisPoints() +{ + Rect current = GetContentRect(); + start_.x = current.GetLeft(); + end_.x = current.GetRight(); + start_.y = enableReverse_ ? current.GetTop() : current.GetBottom(); + end_.y = start_.y; +} + +bool UIXAxis::UpdateAxis() +{ + UpdateAxisPoints(); + int16_t xAxisLength = end_.x - start_.x + 1; + if (xAxisLength <= 0) { + return false; + } + + if (markDataCount_ != 0) { + dataInterval_ = static_cast((maxRange_ - minRange_) / markDataCount_); + markInterval_ = static_cast(xAxisLength) / markDataCount_; + if (maxRange_ > minRange_) { + dataPerMark_ = markInterval_ / dataInterval_; + } + } + + return true; +} + +void UIXAxis::TranslateToPixel(int16_t& value) +{ + float minXStep = dataPerMark_ ? dataPerMark_ : markInterval_; + value = start_.x + static_cast((value - minRange_) * minXStep); +} + +void UIAxis::OnDraw(const Rect& invalidatedArea) +{ + DrawLine::Draw(start_, end_, invalidatedArea, style_->lineWidth_, style_->lineColor_, style_->lineOpa_); + DrawAxisMark(invalidatedArea); +} + +void UIXAxis::DrawAxisMark(const Rect& invalidatedArea) +{ + Point start; + Point end; + uint16_t index = 1; + while (index <= markDataCount_) { + start.y = start_.y; + start.x = start_.x + static_cast(index * markInterval_); + end.y = enableReverse_ ? (start.y + AXIS_DEFAULT_MARK_LENGTH) : (start.y - AXIS_DEFAULT_MARK_LENGTH); + end.x = start.x; + + DrawLine::Draw(start, end, invalidatedArea, style_->lineWidth_, style_->lineColor_, style_->lineOpa_); + index++; + } +} + +void UIYAxis::SetMarkNum(uint16_t count) +{ + if ((count == 0) || (count > Screen::GetInstance().GetHeight())) { + return; + } + markDataCount_ = count; + dataInterval_ = static_cast((maxRange_ - minRange_) / markDataCount_); +} + +bool UIYAxis::SetDataRange(uint16_t min, uint16_t max) +{ + if (max <= min) { + return false; + } + + maxRange_ = max; + minRange_ = min; + return UpdateAxis(); +} + +void UIYAxis::UpdateAxisPoints() +{ + Rect current = GetContentRect(); + int16_t top = current.GetTop(); + int16_t bottom = current.GetBottom(); + + start_.x = current.GetLeft(); + end_.x = start_.x; + if (enableReverse_) { + start_.y = top; + end_.y = bottom; + } else { + start_.y = bottom; + end_.y = top; + } +} + +void UIYAxis::TranslateToPixel(int16_t& value) +{ + float minYStep = dataPerMark_ ? dataPerMark_ : markInterval_; + if (enableReverse_) { + value = start_.y + static_cast((maxRange_ - value + minRange_) * minYStep); + } else { + value = start_.y - static_cast((value - minRange_) * minYStep); + } +} + +bool UIYAxis::UpdateAxis() +{ + UpdateAxisPoints(); + int16_t yAxisLength = enableReverse_ ? (end_.y - start_.y + 1) : (start_.y - end_.y + 1); + if (yAxisLength <= 0) { + return false; + } + + if (markDataCount_ != 0) { + dataInterval_ = static_cast((maxRange_ - minRange_) / markDataCount_); + markInterval_ = static_cast(yAxisLength) / markDataCount_; + if (dataInterval_ != 0) { + dataPerMark_ = markInterval_ / dataInterval_; + } + } + return true; +} + +void UIYAxis::DrawAxisMark(const Rect& invalidatedArea) +{ + uint16_t index = 1; + while (index <= markDataCount_) { + Point start; + Point end; + start.x = start_.x; + start.y = enableReverse_ ? (start_.y + static_cast(index * markInterval_)) + : (start_.y - static_cast(index * markInterval_)); + end.x = start.x + AXIS_DEFAULT_MARK_LENGTH; + end.y = start.y; + + DrawLine::Draw(start, end, invalidatedArea, style_->lineWidth_, style_->lineColor_, style_->lineOpa_); + index++; + } +} +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/components/ui_box_progress.cpp b/frameworks/components/ui_box_progress.cpp new file mode 100755 index 0000000..27534d7 --- /dev/null +++ b/frameworks/components/ui_box_progress.cpp @@ -0,0 +1,237 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "components/ui_box_progress.h" +#include "draw/draw_arc.h" +#include "draw/draw_rect.h" +#include "graphic_log.h" + +namespace OHOS { +UIBoxProgress::UIBoxProgress() + : progressWidth_(0), progressHeight_(0), isValidWidthSet_(false), isValidHeightSet_(false) +{ + SetDirection(Direction::DIR_LEFT_TO_RIGHT); +} + +void UIBoxProgress::DrawValidRect(const Image* image, const Rect& rect, const Rect& invalidatedArea, + const Style& style, uint16_t radius) +{ + Rect cordsTmp; + if ((image != nullptr) && (image->GetSrcType() != IMG_SRC_UNKNOWN)) { + ImageHeader header = {0}; + image->GetHeader(header); + + Rect area(rect); + switch (direction_) { + case Direction::DIR_LEFT_TO_RIGHT: + cordsTmp.SetPosition(area.GetLeft() - radius, area.GetTop()); + break; + case Direction::DIR_TOP_TO_BOTTOM: + cordsTmp.SetPosition(area.GetLeft(), area.GetTop() - radius); + break; + case Direction::DIR_RIGHT_TO_LEFT: + cordsTmp.SetPosition(area.GetRight() + radius - header.width, area.GetTop()); + break; + case Direction::DIR_BOTTOM_TO_TOP: + cordsTmp.SetPosition(area.GetLeft(), area.GetBottom() + radius - header.height); + break; + default: + GRAPHIC_LOGE("UIBoxProgress: DrawValidRect direction Err!\n"); + break; + } + cordsTmp.SetHeight(header.height); + cordsTmp.SetWidth(header.width); + if (area.Intersect(area, invalidatedArea)) { + image->DrawImage(cordsTmp, area, style, opaScale_); + } + } else { + DrawRect::Draw(rect, invalidatedArea, style, opaScale_); + } + + if (style.lineCap_ == CapType::CAP_ROUND) { + DrawRoundCap(image, {cordsTmp.GetX(), cordsTmp.GetY()}, rect, invalidatedArea, radius, style); + } +} + +void UIBoxProgress::DrawRoundCap(const Image* image, const Point& imgPos, const Rect& rect, + const Rect& invalidatedArea, uint16_t radius, const Style& style) +{ + Point leftTop; + Point leftBottom; + Point rightTop; + Point rightBottom; + + switch (direction_) { + case Direction::DIR_LEFT_TO_RIGHT: + case Direction::DIR_RIGHT_TO_LEFT: { + leftTop.x = rect.GetLeft() - 1; + leftTop.y = rect.GetTop() + radius - 1; + leftBottom.x = leftTop.x; + leftBottom.y = rect.GetBottom() - radius + 1; + rightTop.x = rect.GetRight() + 1; + rightTop.y = leftTop.y; + rightBottom.x = rightTop.x; + rightBottom.y = leftBottom.y; + break; + } + + case Direction::DIR_TOP_TO_BOTTOM: + case Direction::DIR_BOTTOM_TO_TOP: { + leftTop.x = rect.GetLeft() + radius - 1; + leftTop.y = rect.GetTop() - 1; + rightTop.x = rect.GetRight() - radius + 1; + rightTop.y = leftTop.y; + leftBottom.x = leftTop.x; + leftBottom.y = rect.GetBottom() + 1; + rightBottom.x = rightTop.x; + rightBottom.y = leftBottom.y; + break; + } + default: + GRAPHIC_LOGE("UIBoxProgress: DrawRoundCap direction Err!\n"); + break; + } + + Style capStyle = style; + capStyle.lineWidth_ = radius; + capStyle.lineColor_ = style.bgColor_; + capStyle.lineOpa_ = style.bgOpa_; + ArcInfo arcInfo = {{0}}; + arcInfo.radius = radius; + arcInfo.imgPos = imgPos; + arcInfo.imgSrc = image; + + arcInfo.center = leftTop; + arcInfo.startAngle = THREE_QUARTER_IN_DEGREE; + arcInfo.endAngle = 0; + DrawArc::GetInstance()->Draw(arcInfo, invalidatedArea, capStyle, opaScale_, CapType::CAP_NONE); + + arcInfo.center = leftBottom; + arcInfo.startAngle = SEMICIRCLE_IN_DEGREE; + arcInfo.endAngle = THREE_QUARTER_IN_DEGREE; + DrawArc::GetInstance()->Draw(arcInfo, invalidatedArea, capStyle, opaScale_, CapType::CAP_NONE); + + arcInfo.center = rightTop; + arcInfo.startAngle = 0; + arcInfo.endAngle = THREE_QUARTER_IN_DEGREE; + DrawArc::GetInstance()->Draw(arcInfo, invalidatedArea, capStyle, opaScale_, CapType::CAP_NONE); + + arcInfo.center = rightBottom; + arcInfo.startAngle = THREE_QUARTER_IN_DEGREE; + arcInfo.endAngle = SEMICIRCLE_IN_DEGREE; + DrawArc::GetInstance()->Draw(arcInfo, invalidatedArea, capStyle, opaScale_, CapType::CAP_NONE); +} + +void UIBoxProgress::GetBackgroundParam(Point& startPoint, int16_t& width, int16_t& height, uint16_t& radius, + const Style& style) +{ + Rect rect = GetOrigRect(); + startPoint.x = rect.GetLeft() + style_->borderWidth_ + style_->paddingLeft_; + startPoint.y = rect.GetTop() + style_->borderWidth_ + style_->paddingTop_; + + radius = 0; + width = progressWidth_; + height = progressHeight_; + if (style.lineCap_ == CapType::CAP_ROUND) { + switch (direction_) { + case Direction::DIR_LEFT_TO_RIGHT: + case Direction::DIR_RIGHT_TO_LEFT: + radius = (progressHeight_ + 1) >> 1; + width -= radius << 1; + startPoint.x += radius; + break; + case Direction::DIR_TOP_TO_BOTTOM: + case Direction::DIR_BOTTOM_TO_TOP: + radius = (progressWidth_ + 1) >> 1; + height -= radius << 1; + startPoint.y += radius; + break; + default: + GRAPHIC_LOGE("UIBoxProgress: GetBackgroundParam direction Err!\n"); + return; + } + } +} + +void UIBoxProgress::DrawBackground(const Rect& invalidatedArea) +{ + Point startPoint; + int16_t progressWidth; + int16_t progressHeight; + uint16_t radius; + GetBackgroundParam(startPoint, progressWidth, progressHeight, radius, *backgroundStyle_); + + Rect coords(startPoint.x, startPoint.y, startPoint.x + progressWidth - 1, startPoint.y + progressHeight - 1); + + DrawValidRect(backgroundImage_, coords, invalidatedArea, *backgroundStyle_, radius); +} + +void UIBoxProgress::DrawForeground(const Rect& invalidatedArea, Rect& coords) +{ + Point startPoint; + int16_t progressWidth; + int16_t progressHeight; + uint16_t radius; + GetBackgroundParam(startPoint, progressWidth, progressHeight, radius, *foregroundStyle_); + int16_t length; + + switch (direction_) { + case Direction::DIR_LEFT_TO_RIGHT: { + length = GetCurrentPos(progressWidth - 1); + coords.SetRect(startPoint.x, startPoint.y, startPoint.x + length, startPoint.y + progressHeight - 1); + break; + } + case Direction::DIR_RIGHT_TO_LEFT: { + length = GetCurrentPos(progressWidth - 1); + coords.SetRect(startPoint.x + progressWidth - 1 - length, + startPoint.y, startPoint.x + progressWidth - 1, startPoint.y + progressHeight - 1); + break; + } + case Direction::DIR_TOP_TO_BOTTOM: { + length = GetCurrentPos(progressHeight - 1); + coords.SetRect(startPoint.x, startPoint.y, startPoint.x + progressWidth - 1, startPoint.y + length); + break; + } + case Direction::DIR_BOTTOM_TO_TOP: { + length = GetCurrentPos(progressHeight - 1); + coords.SetRect(startPoint.x, startPoint.y + progressHeight - 1 - length, + startPoint.x + progressWidth - 1, startPoint.y + progressHeight - 1); + break; + } + default: { + GRAPHIC_LOGE("UIBoxProgress: DrawForeground direction Err!\n"); + return; + } + } + + DrawValidRect(foregroundImage_, coords, invalidatedArea, *foregroundStyle_, radius); +} + +void UIBoxProgress::OnDraw(const Rect& invalidatedArea) +{ + DrawRect::Draw(GetOrigRect(), invalidatedArea, *style_, opaScale_); + Rect trunc(invalidatedArea); + if (trunc.Intersect(trunc, GetOrigRect())) { + if (enableBackground_) { + DrawBackground(trunc); + } + + if ((lastValue_ - rangeMin_ != 0) || (foregroundStyle_->lineCap_ == CapType::CAP_ROUND)) { + Rect coords; + DrawForeground(trunc, coords); + } + } +} +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/components/ui_button.cpp b/frameworks/components/ui_button.cpp new file mode 100755 index 0000000..18d9d31 --- /dev/null +++ b/frameworks/components/ui_button.cpp @@ -0,0 +1,278 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "components/ui_button.h" +#include "common/image.h" +#include "draw/draw_image.h" +#include "draw/draw_rect.h" +#include "graphic_log.h" +#include "imgdecode/cache_manager.h" +#include "style.h" +#include "themes/theme_manager.h" + +namespace OHOS { +UIButton::UIButton() + : defaultImgSrc_(nullptr), + triggeredImgSrc_(nullptr), + currentImgSrc_(ButtonImageSrc::BTN_IMAGE_DEFAULT), + imgX_(0), + imgY_(0), + contentWidth_(0), + contentHeight_(0), + state_(RELEASED), + styleState_(RELEASED), + buttonStyleAllocFlag_(false) +{ + touchable_ = true; + SetupThemeStyles(); +} + +UIButton::~UIButton() +{ + if (defaultImgSrc_ != nullptr) { + delete defaultImgSrc_; + defaultImgSrc_ = nullptr; + } + + if (triggeredImgSrc_ != nullptr) { + delete triggeredImgSrc_; + triggeredImgSrc_ = nullptr; + } + + if (buttonStyleAllocFlag_) { + for (uint8_t i = 0; i < BTN_STATE_NUM; i++) { + delete buttonStyles_[i]; + buttonStyles_[i] = nullptr; + } + buttonStyleAllocFlag_ = false; + } +} + +void UIButton::DrawImg(const Rect& invalidatedArea, OpacityType opaScale) +{ + const Image* image = GetCurImageSrc(); + if (image == nullptr) { + return; + } + + ImageHeader header = {0}; + image->GetHeader(header); + Rect coords; + Rect viewRect = GetContentRect(); + coords.SetLeft(viewRect.GetLeft() + GetImageX()); + coords.SetTop(viewRect.GetTop() + GetImageY()); + coords.SetWidth(header.width); + coords.SetHeight(header.height); + + Rect trunc(invalidatedArea); + if (trunc.Intersect(trunc, viewRect)) { + image->DrawImage(coords, trunc, *buttonStyles_[state_], opaScale); + } +} + +void UIButton::OnDraw(const Rect& invalidatedArea) +{ + OpacityType opa = GetMixOpaScale(); + DrawRect::Draw(GetOrigRect(), invalidatedArea, *buttonStyles_[state_], opa); + DrawImg(invalidatedArea, opa); +} + +void UIButton::SetupThemeStyles() +{ + Theme* theme = ThemeManager::GetInstance().GetCurrent(); + + if (theme == nullptr) { + buttonStyles_[RELEASED] = &(StyleDefault::GetButtonReleasedStyle()); + buttonStyles_[PRESSED] = &(StyleDefault::GetButtonPressedStyle()); + buttonStyles_[INACTIVE] = &(StyleDefault::GetButtonInactiveStyle()); + } else { + buttonStyles_[RELEASED] = &(theme->GetButtonStyle().released); + buttonStyles_[PRESSED] = &(theme->GetButtonStyle().pressed); + buttonStyles_[INACTIVE] = &(theme->GetButtonStyle().inactive); + } +} + +int64_t UIButton::GetStyle(uint8_t key) const +{ + return GetStyleForState(key, styleState_); +} + +void UIButton::SetStyle(uint8_t key, int64_t value) +{ + SetStyleForState(key, value, styleState_); +} + +int64_t UIButton::GetStyleForState(uint8_t key, ButtonState state) const +{ + if (state < BTN_STATE_NUM) { + return (buttonStyles_[state])->GetStyle(key); + } + return 0; +} + +void UIButton::SetStyleForState(uint8_t key, int64_t value, ButtonState state) +{ + if (state < BTN_STATE_NUM) { + if (!buttonStyleAllocFlag_) { + for (uint8_t i = 0; i < BTN_STATE_NUM; i++) { + Style styleSaved = *buttonStyles_[i]; + buttonStyles_[i] = new Style; + if (buttonStyles_[i] == nullptr) { + GRAPHIC_LOGE("new Style fail"); + return; + } + *(buttonStyles_[i]) = styleSaved; + } + buttonStyleAllocFlag_ = true; + } + int16_t width = GetWidth(); + int16_t height = GetHeight(); + buttonStyles_[state]->SetStyle(key, value); + switch (key) { + case STYLE_BORDER_WIDTH: { + SetWidth(width); + SetHeight(height); + break; + } + case STYLE_PADDING_LEFT: + case STYLE_PADDING_RIGHT: { + SetWidth(width); + break; + } + case STYLE_PADDING_TOP: + case STYLE_PADDING_BOTTOM: { + SetHeight(height); + break; + } + default: + break; + } + } +} + +bool UIButton::OnPressEvent(const PressEvent& event) +{ + currentImgSrc_ = ButtonImageSrc::BTN_IMAGE_TRIGGERED; + SetState(PRESSED); + Resize(contentWidth_, contentHeight_); + Invalidate(); + return UIView::OnPressEvent(event); +} + +bool UIButton::OnReleaseEvent(const ReleaseEvent& event) +{ + currentImgSrc_ = ButtonImageSrc::BTN_IMAGE_DEFAULT; + SetState(RELEASED); + Resize(contentWidth_, contentHeight_); + Invalidate(); + return UIView::OnReleaseEvent(event); +} + +bool UIButton::OnCancelEvent(const CancelEvent& event) +{ + currentImgSrc_ = ButtonImageSrc::BTN_IMAGE_DEFAULT; + SetState(RELEASED); + Resize(contentWidth_, contentHeight_); + Invalidate(); + return UIView::OnCancelEvent(event); +} + +const Image* UIButton::GetCurImageSrc() const +{ + if (currentImgSrc_ == ButtonImageSrc::BTN_IMAGE_DEFAULT) { + return defaultImgSrc_; + } else if (currentImgSrc_ == ButtonImageSrc::BTN_IMAGE_TRIGGERED) { + return triggeredImgSrc_; + } else { + return nullptr; + } +} + +void UIButton::SetImageSrc(const char* defaultImgSrc, const char* triggeredImgSrc) +{ + if (!InitImage()) { + return; + } + defaultImgSrc_->SetSrc(defaultImgSrc); + triggeredImgSrc_->SetSrc(triggeredImgSrc); +} + +void UIButton::SetImageSrc(const ImageInfo* defaultImgSrc, const ImageInfo* triggeredImgSrc) +{ + if (!InitImage()) { + return; + } + defaultImgSrc_->SetSrc(defaultImgSrc); + triggeredImgSrc_->SetSrc(triggeredImgSrc); +} + +void UIButton::Disable() +{ + SetState(INACTIVE); + touchable_ = false; +} + +void UIButton::Enable() +{ + SetState(RELEASED); + touchable_ = true; +} + +void UIButton::SetState(ButtonState state) +{ + state_ = state; + Invalidate(); +} + +bool UIButton::InitImage() +{ + if (defaultImgSrc_ == nullptr) { + defaultImgSrc_ = new Image(); + if (defaultImgSrc_ == nullptr) { + GRAPHIC_LOGE("new Image fail"); + return false; + } + } + if (triggeredImgSrc_ == nullptr) { + triggeredImgSrc_ = new Image(); + if (triggeredImgSrc_ == nullptr) { + GRAPHIC_LOGE("new Image fail"); + return false; + } + } + return true; +} + +bool UIButton::OnPreDraw(Rect& invalidatedArea) const +{ + Rect rect(GetRect()); + int16_t r = buttonStyles_[styleState_]->borderRadius_; + if (r == COORD_MAX) { + return true; + } + if (r != 0) { + r = ((r & 0x1) == 0) ? (r >> 1) : ((r + 1) >> 1); + rect.SetLeft(rect.GetX() + r); + rect.SetWidth(rect.GetWidth() - r); + rect.SetTop(rect.GetY() + r); + rect.SetHeight(rect.GetHeight() - r); + } + if (rect.IsContains(invalidatedArea)) { + return true; + } + invalidatedArea.Intersect(invalidatedArea, rect); + return false; +} +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/components/ui_canvas.cpp b/frameworks/components/ui_canvas.cpp new file mode 100755 index 0000000..e7b52b8 --- /dev/null +++ b/frameworks/components/ui_canvas.cpp @@ -0,0 +1,807 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "components/ui_canvas.h" +#include "common/image.h" +#include "draw/draw_arc.h" +#include "draw/draw_curve.h" +#include "draw/draw_image.h" +#include "draw/draw_line.h" +#include "draw/draw_rect.h" +#include "graphic_log.h" + +namespace OHOS { +UICanvas::UICanvasPath::~UICanvasPath() +{ + points_.Clear(); + cmd_.Clear(); + arcParam_.Clear(); +} + +void UICanvas::BeginPath() +{ + /* If the previous path is not added to the drawing linked list, it should be destroyed directly. */ + if (path_ != nullptr && path_->strokeCount_ == 0) { + delete path_; + path_ = nullptr; + } + + path_ = new UICanvasPath(); + if (path_ == nullptr) { + GRAPHIC_LOGE("new UICanvasPath fail"); + return; + } +} + +void UICanvas::MoveTo(const Point& point) +{ + if (path_ == nullptr) { + return; + } + + path_->startPos_ = point; + /* If the previous command is also CMD_MOVE_TO, the previous command is overwritten. */ + if ((path_->cmd_.Size() != 0) && (path_->cmd_.Tail()->data_ == CMD_MOVE_TO)) { + path_->points_.Tail()->data_ = point; + return; + } + path_->points_.PushBack(point); + path_->cmd_.PushBack(CMD_MOVE_TO); +} + +void UICanvas::LineTo(const Point& point) +{ + if (path_ == nullptr) { + return; + } + + path_->points_.PushBack(point); + if (path_->cmd_.Size() == 0) { + path_->startPos_ = point; + path_->cmd_.PushBack(CMD_MOVE_TO); + } else { + path_->cmd_.PushBack(CMD_LINE_TO); + } +} + +void UICanvas::ArcTo(const Point& center, uint16_t radius, int16_t startAngle, int16_t endAngle) +{ + if (path_ == nullptr) { + return; + } + + /* + * If there is no command before CMD_ARC, only the arc is drawn. If there is a command in front of + * CMD_ARC, the start point of arc must be connected to the end point of the path. + */ + float sinma = radius * Sin(startAngle); + float cosma = radius * Sin(QUARTER_IN_DEGREE - startAngle); + if (path_->cmd_.Size() != 0) { + path_->points_.PushBack({MATH_ROUND(center.x + sinma), MATH_ROUND(center.y - cosma)}); + path_->cmd_.PushBack(CMD_LINE_TO); + } else { + path_->startPos_ = {MATH_ROUND(center.x + sinma), MATH_ROUND(center.y - cosma)}; + } + + /* If the ARC scan range exceeds 360 degrees, the end point of the path is the position of the start angle. */ + if (MATH_ABS(startAngle - endAngle) < CIRCLE_IN_DEGREE) { + sinma = radius * Sin(endAngle); + cosma = radius * Sin(QUARTER_IN_DEGREE - endAngle); + } + path_->points_.PushBack({MATH_ROUND(center.x + sinma), MATH_ROUND(center.y - cosma)}); + path_->cmd_.PushBack(CMD_ARC); + + int16_t start; + int16_t end; + if (startAngle > endAngle) { + start = endAngle; + end = startAngle; + } else { + start = startAngle; + end = endAngle; + } + + DrawArc::GetInstance()->GetDrawRange(start, end); + ArcParam param; + param.center = center; + param.radius = radius; + param.startAngle = start; + param.endAngle = end; + path_->arcParam_.PushBack(param); +} + +void UICanvas::AddRect(const Point& point, int16_t height, int16_t width) +{ + if (path_ == nullptr) { + return; + } + + MoveTo(point); + LineTo({static_cast(point.x + width), point.y}); + LineTo({static_cast(point.x + width), static_cast(point.y + height)}); + LineTo({point.x, static_cast(point.y + height)}); + ClosePath(); +} + +void UICanvas::ClosePath() +{ + if ((path_ == nullptr) || (path_->cmd_.Size() == 0)) { + return; + } + + path_->points_.PushBack(path_->startPos_); + path_->cmd_.PushBack(CMD_CLOSE); +} + +UICanvas::~UICanvas() +{ + if ((path_ != nullptr) && (path_->strokeCount_ == 0)) { + delete path_; + path_ = nullptr; + } + + void* param = nullptr; + ListNode* curDraw = drawCmdList_.Begin(); + for (; curDraw != drawCmdList_.End(); curDraw = curDraw->next_) { + param = curDraw->data_.param; + curDraw->data_.DeleteParam(param); + curDraw->data_.param = nullptr; + } + drawCmdList_.Clear(); +} + +void UICanvas::Clear() +{ + if ((path_ != nullptr) && (path_->strokeCount_ == 0)) { + delete path_; + path_ = nullptr; + } + + void* param = nullptr; + ListNode* curDraw = drawCmdList_.Begin(); + for (; curDraw != drawCmdList_.End(); curDraw = curDraw->next_) { + param = curDraw->data_.param; + curDraw->data_.DeleteParam(param); + curDraw->data_.param = nullptr; + } + drawCmdList_.Clear(); + Invalidate(); +} + +void UICanvas::DrawLine(const Point& endPoint, const Paint& paint) +{ + DrawLine(startPoint_, endPoint, paint); +} + +void UICanvas::DrawLine(const Point& startPoint, const Point& endPoint, const Paint& paint) +{ + LineParam* lineParam = new LineParam; + if (lineParam == nullptr) { + GRAPHIC_LOGE("new LineParam fail"); + return; + } + lineParam->start = startPoint; + lineParam->end = endPoint; + + DrawCmd cmd; + cmd.paint = paint; + cmd.param = lineParam; + cmd.DeleteParam = DeleteLineParam; + cmd.DrawGraphics = DoDrawLine; + drawCmdList_.PushBack(cmd); + + Invalidate(); + SetStartPosition(endPoint); +} + +void UICanvas::DrawCurve(const Point& control1, const Point& control2, const Point& endPoint, const Paint& paint) +{ + DrawCurve(startPoint_, control1, control2, endPoint, paint); +} + +void UICanvas::DrawCurve(const Point& startPoint, + const Point& control1, + const Point& control2, + const Point& endPoint, + const Paint& paint) +{ + CurveParam* curveParam = new CurveParam; + if (curveParam == nullptr) { + GRAPHIC_LOGE("new CurveParam fail"); + return; + } + curveParam->start = startPoint; + curveParam->control1 = control1; + curveParam->control2 = control2; + curveParam->end = endPoint; + + DrawCmd cmd; + cmd.paint = paint; + if (paint.GetStrokeWidth() > MAX_CURVE_WIDTH) { + cmd.paint.SetStrokeWidth(MAX_CURVE_WIDTH); + } + cmd.param = curveParam; + cmd.DeleteParam = DeleteCurveParam; + cmd.DrawGraphics = DoDrawCurve; + drawCmdList_.PushBack(cmd); + + Invalidate(); + SetStartPosition(endPoint); +} + +void UICanvas::DrawRect(const Point& startPoint, int16_t height, int16_t width, const Paint& paint) +{ + if (static_cast(paint.GetStyle()) & Paint::PaintStyle::STROKE_STYLE) { + RectParam* rectParam = new RectParam; + if (rectParam == nullptr) { + GRAPHIC_LOGE("new RectParam fail"); + return; + } + rectParam->start = startPoint; + rectParam->height = height; + rectParam->width = width; + + DrawCmd cmd; + cmd.paint = paint; + cmd.param = rectParam; + cmd.DeleteParam = DeleteRectParam; + cmd.DrawGraphics = DoDrawRect; + drawCmdList_.PushBack(cmd); + } + + if (static_cast(paint.GetStyle()) & Paint::PaintStyle::FILL_STYLE) { + RectParam* rectParam = new RectParam; + if (rectParam == nullptr) { + GRAPHIC_LOGE("new RectParam fail"); + return; + } + rectParam->start = startPoint; + rectParam->height = height; + rectParam->width = width; + + DrawCmd cmd; + cmd.paint = paint; + cmd.param = rectParam; + cmd.DeleteParam = DeleteRectParam; + cmd.DrawGraphics = DoFillRect; + drawCmdList_.PushBack(cmd); + } + + Invalidate(); +} + +void UICanvas::DrawCircle(const Point& center, uint16_t radius, const Paint& paint) +{ + CircleParam* circleParam = new CircleParam; + if (circleParam == nullptr) { + GRAPHIC_LOGE("new CircleParam fail"); + return; + } + circleParam->center = center; + circleParam->radius = radius; + + DrawCmd cmd; + cmd.paint = paint; + cmd.param = circleParam; + cmd.DeleteParam = DeleteCircleParam; + cmd.DrawGraphics = DoDrawCircle; + drawCmdList_.PushBack(cmd); + + Invalidate(); +} + +void UICanvas::DrawSector(const Point& center, + uint16_t radius, + int16_t startAngle, + int16_t endAngle, + const Paint& paint) +{ + if (static_cast(paint.GetStyle()) & Paint::PaintStyle::FILL_STYLE) { + Paint innerPaint = paint; + innerPaint.SetStyle(Paint::PaintStyle::STROKE_STYLE); + innerPaint.SetStrokeWidth(radius); + innerPaint.SetStrokeColor(paint.GetFillColor()); + radius >>= 1; + DrawArc(center, radius, startAngle, endAngle, innerPaint); + } +} + +void UICanvas::DrawArc(const Point& center, uint16_t radius, int16_t startAngle, int16_t endAngle, const Paint& paint) +{ + if (static_cast(paint.GetStyle()) & Paint::PaintStyle::STROKE_STYLE) { + ArcParam* arcParam = new ArcParam; + if (arcParam == nullptr) { + GRAPHIC_LOGE("new ArcParam fail"); + return; + } + arcParam->center = center; + arcParam->radius = radius; + + int16_t start; + int16_t end; + if (startAngle > endAngle) { + start = endAngle; + end = startAngle; + } else { + start = startAngle; + end = endAngle; + } + + DrawArc::GetInstance()->GetDrawRange(start, end); + arcParam->startAngle = start; + arcParam->endAngle = end; + + DrawCmd cmd; + cmd.paint = paint; + cmd.param = arcParam; + cmd.DeleteParam = DeleteArcParam; + cmd.DrawGraphics = DoDrawArc; + drawCmdList_.PushBack(cmd); + + Invalidate(); + } +} + +void UICanvas::DrawLabel(const Point& startPoint, + const char* text, + uint16_t maxWidth, + const FontStyle& fontStyle, + const Paint& paint) +{ + if (text == nullptr) { + return; + } + if (static_cast(paint.GetStyle()) & Paint::PaintStyle::FILL_STYLE) { + UILabel* label = new UILabel(); + if (label == nullptr) { + GRAPHIC_LOGE("new UILabel fail"); + return; + } + label->SetLineBreakMode(UILabel::LINE_BREAK_CLIP); + label->SetPosition(startPoint.x, startPoint.y); + label->SetWidth(maxWidth); + label->SetHeight(GetHeight()); + label->SetText(text); + label->SetFont(fontStyle.fontName, fontStyle.fontSize); + label->SetAlign(fontStyle.align); + label->SetDirect(fontStyle.direct); + label->SetStyle(STYLE_LETTER_SPACE, fontStyle.letterSpace); + label->SetStyle(STYLE_TEXT_COLOR, paint.GetFillColor().full); + label->SetStyle(STYLE_TEXT_OPA, paint.GetOpacity()); + + DrawCmd cmd; + cmd.param = label; + cmd.DeleteParam = DeleteLabel; + cmd.DrawGraphics = DoDrawLabel; + drawCmdList_.PushBack(cmd); + + Invalidate(); + } +} + +void UICanvas::DrawImage(const Point& startPoint, const char* image, const Paint& paint) +{ + if (image == nullptr) { + return; + } + + ImageParam* imageParam = new ImageParam; + if (imageParam == nullptr) { + GRAPHIC_LOGE("new ImageParam fail"); + return; + } + imageParam->image = new Image(); + if (imageParam->image == nullptr) { + delete imageParam; + imageParam = nullptr; + return; + } + + imageParam->image->SetSrc(image); + ImageHeader header = {0}; + imageParam->image->GetHeader(header); + imageParam->start = startPoint; + imageParam->height = header.height; + imageParam->width = header.width; + + DrawCmd cmd; + cmd.paint = paint; + cmd.param = imageParam; + cmd.DeleteParam = DeleteImageParam; + cmd.DrawGraphics = DoDrawImage; + drawCmdList_.PushBack(cmd); + + Invalidate(); +} + +void UICanvas::DrawPath(const Paint& paint) +{ + if ((path_ == nullptr) || (path_->cmd_.Size() == 0)) { + return; + } + + path_->strokeCount_++; + PathParam* param = new PathParam; + if (param == nullptr) { + GRAPHIC_LOGE("new PathParam fail"); + return; + } + param->path = path_; + param->count = path_->cmd_.Size(); + + DrawCmd cmd; + cmd.paint = paint; + cmd.param = param; + cmd.DeleteParam = DeletePathParam; + cmd.DrawGraphics = DoDrawPath; + drawCmdList_.PushBack(cmd); + Invalidate(); +} + +void UICanvas::OnDraw(const Rect& invalidatedArea) +{ + Rect rect = GetOrigRect(); + DrawRect::Draw(rect, invalidatedArea, *style_, opaScale_); + + void* param = nullptr; + ListNode* curDraw = drawCmdList_.Begin(); + Rect coords = GetOrigRect(); + Rect trunc = invalidatedArea; + if (trunc.Intersect(trunc, coords)) { + for (; curDraw != drawCmdList_.End(); curDraw = curDraw->next_) { + param = curDraw->data_.param; + curDraw->data_.DrawGraphics(param, curDraw->data_.paint, rect, trunc, *style_); + } + } +} + +void UICanvas::GetAbsolutePosition(const Point& prePoint, const Rect& rect, const Style& style, Point& point) +{ + point.x = prePoint.x + rect.GetLeft() + style.paddingLeft_ + style.borderWidth_; + point.y = prePoint.y + rect.GetTop() + style.paddingTop_ + style.borderWidth_; +} + +void UICanvas::DoDrawLine(void* param, + const Paint& paint, + const Rect& rect, + const Rect& invalidatedArea, + const Style& style) +{ + if (param == nullptr) { + return; + } + LineParam* lineParam = static_cast(param); + Point start; + Point end; + GetAbsolutePosition(lineParam->start, rect, style, start); + GetAbsolutePosition(lineParam->end, rect, style, end); + + DrawLine::Draw(start, end, invalidatedArea, paint.GetStrokeWidth(), paint.GetStrokeColor(), paint.GetOpacity()); +} + +void UICanvas::DoDrawCurve(void* param, + const Paint& paint, + const Rect& rect, + const Rect& invalidatedArea, + const Style& style) +{ + if (param == nullptr) { + return; + } + CurveParam* curveParam = static_cast(param); + Point start; + Point end; + Point control1; + Point control2; + GetAbsolutePosition(curveParam->start, rect, style, start); + GetAbsolutePosition(curveParam->end, rect, style, end); + GetAbsolutePosition(curveParam->control1, rect, style, control1); + GetAbsolutePosition(curveParam->control2, rect, style, control2); + + DrawCurve::DrawCubicBezier(start, control1, control2, end, invalidatedArea, paint.GetStrokeWidth(), + paint.GetStrokeColor(), paint.GetOpacity()); +} + +void UICanvas::DoDrawRect(void* param, + const Paint& paint, + const Rect& rect, + const Rect& invalidatedArea, + const Style& style) +{ + if (param == nullptr) { + return; + } + RectParam* rectParam = static_cast(param); + Style drawStyle = StyleDefault::GetDefaultStyle(); + drawStyle.bgColor_ = paint.GetStrokeColor(); + drawStyle.bgOpa_ = paint.GetOpacity(); + drawStyle.borderRadius_ = 0; + + int16_t lineWidth = static_cast(paint.GetStrokeWidth()); + Point start; + GetAbsolutePosition(rectParam->start, rect, style, start); + + int16_t x = start.x - lineWidth / 2; // 2: half + int16_t y = start.y - lineWidth / 2; // 2: half + Rect coords; + if ((rectParam->height <= lineWidth) || (rectParam->width <= lineWidth)) { + coords.SetPosition(x, y); + coords.SetHeight(rectParam->height + lineWidth); + coords.SetWidth(rectParam->width + lineWidth); + DrawRect::Draw(coords, invalidatedArea, drawStyle, OPA_OPAQUE); + return; + } + + coords.SetPosition(x, y); + coords.SetHeight(lineWidth); + coords.SetWidth(rectParam->width); + DrawRect::Draw(coords, invalidatedArea, drawStyle, OPA_OPAQUE); + + coords.SetPosition(x + rectParam->width, y); + coords.SetHeight(rectParam->height); + coords.SetWidth(lineWidth); + DrawRect::Draw(coords, invalidatedArea, drawStyle, OPA_OPAQUE); + + coords.SetPosition(x, y + lineWidth); + coords.SetHeight(rectParam->height); + coords.SetWidth(lineWidth); + DrawRect::Draw(coords, invalidatedArea, drawStyle, OPA_OPAQUE); + + coords.SetPosition(x + lineWidth, y + rectParam->height); + coords.SetHeight(lineWidth); + coords.SetWidth(rectParam->width); + DrawRect::Draw(coords, invalidatedArea, drawStyle, OPA_OPAQUE); +} + +void UICanvas::DoFillRect(void* param, + const Paint& paint, + const Rect& rect, + const Rect& invalidatedArea, + const Style& style) +{ + if (param == nullptr) { + return; + } + RectParam* rectParam = static_cast(param); + uint8_t enableStroke = static_cast(paint.GetStyle()) & Paint::PaintStyle::STROKE_STYLE; + int16_t lineWidth = enableStroke ? paint.GetStrokeWidth() : 0; + if ((rectParam->height <= lineWidth) || (rectParam->width <= lineWidth)) { + return; + } + Point start; + GetAbsolutePosition(rectParam->start, rect, style, start); + + Rect coords; + coords.SetPosition(start.x + (lineWidth + 1) / 2, start.y + (lineWidth + 1) / 2); // 2: half + coords.SetHeight(rectParam->height - lineWidth); + coords.SetWidth(rectParam->width - lineWidth); + + Style drawStyle = StyleDefault::GetDefaultStyle(); + drawStyle.bgColor_ = paint.GetFillColor(); + drawStyle.bgOpa_ = paint.GetOpacity(); + drawStyle.borderRadius_ = 0; + DrawRect::Draw(coords, invalidatedArea, drawStyle, OPA_OPAQUE); +} + +void UICanvas::DoDrawCircle(void* param, + const Paint& paint, + const Rect& rect, + const Rect& invalidatedArea, + const Style& style) +{ + if (param == nullptr) { + return; + } + CircleParam* circleParam = static_cast(param); + + Style drawStyle = StyleDefault::GetDefaultStyle(); + drawStyle.lineOpa_ = paint.GetOpacity(); + + ArcInfo arcInfo = {{0}}; + arcInfo.imgPos = Point{0, 0}; + arcInfo.startAngle = 0; + arcInfo.endAngle = CIRCLE_IN_DEGREE; + GetAbsolutePosition(circleParam->center, rect, style, arcInfo.center); + uint8_t enableStroke = static_cast(paint.GetStyle()) & Paint::PaintStyle::STROKE_STYLE; + uint16_t halfLineWidth = enableStroke ? (paint.GetStrokeWidth() >> 1) : 0; + if (static_cast(paint.GetStyle()) & Paint::PaintStyle::FILL_STYLE) { + arcInfo.radius = circleParam->radius - halfLineWidth; + drawStyle.lineWidth_ = arcInfo.radius; + drawStyle.lineColor_ = paint.GetFillColor(); + DrawArc::GetInstance()->Draw(arcInfo, invalidatedArea, drawStyle, OPA_OPAQUE, CapType::CAP_NONE); + } + + if (enableStroke) { + arcInfo.radius = circleParam->radius + halfLineWidth - 1; + drawStyle.lineWidth_ = static_cast(paint.GetStrokeWidth()); + drawStyle.lineColor_ = paint.GetStrokeColor(); + DrawArc::GetInstance()->Draw(arcInfo, invalidatedArea, drawStyle, OPA_OPAQUE, CapType::CAP_NONE); + } +} + +void UICanvas::DoDrawArc(void* param, + const Paint& paint, + const Rect& rect, + const Rect& invalidatedArea, + const Style& style) +{ + if (param == nullptr) { + return; + } + ArcParam* arcParam = static_cast(param); + + ArcInfo arcInfo = {{0}}; + arcInfo.imgPos = Point{0, 0}; + arcInfo.startAngle = arcParam->startAngle; + arcInfo.endAngle = arcParam->endAngle; + Style drawStyle = StyleDefault::GetDefaultStyle(); + drawStyle.lineWidth_ = static_cast(paint.GetStrokeWidth()); + drawStyle.lineColor_ = paint.GetStrokeColor(); + drawStyle.lineOpa_ = paint.GetOpacity(); + arcInfo.radius = arcParam->radius + ((paint.GetStrokeWidth() + 1) >> 1); + + GetAbsolutePosition(arcParam->center, rect, style, arcInfo.center); + DrawArc::GetInstance()->Draw(arcInfo, invalidatedArea, drawStyle, OPA_OPAQUE, CapType::CAP_NONE); +} + +void UICanvas::DoDrawImage(void* param, + const Paint& paint, + const Rect& rect, + const Rect& invalidatedArea, + const Style& style) +{ + if (param == nullptr) { + return; + } + ImageParam* imageParam = static_cast(param); + + if (imageParam->image == nullptr) { + return; + } + + Point start; + GetAbsolutePosition(imageParam->start, rect, style, start); + + Rect cordsTmp; + cordsTmp.SetPosition(start.x, start.y); + cordsTmp.SetHeight(imageParam->height); + cordsTmp.SetWidth(imageParam->width); + DrawImage::DrawCommon(cordsTmp, invalidatedArea, imageParam->image->GetPath(), style, paint.GetOpacity()); +} + +void UICanvas::DoDrawLabel(void* param, + const Paint& paint, + const Rect& rect, + const Rect& invalidatedArea, + const Style& style) +{ + if (param == nullptr) { + return; + } + UILabel* label = static_cast(param); + Point startPos = {label->GetX(), label->GetY()}; + Point start; + GetAbsolutePosition({startPos.x, startPos.y}, rect, style, start); + label->SetPosition(start.x, start.y); + label->OnDraw(invalidatedArea); + label->SetPosition(startPos.x, startPos.y); +} + +void UICanvas::DoDrawLineJoin(const Point& center, const Rect& invalidatedArea, const Paint& paint) +{ + ArcInfo arcinfo = {{0}}; + arcinfo.center = center; + arcinfo.imgPos = Point{0, 0}; + arcinfo.radius = (paint.GetStrokeWidth() + 1) >> 1; + arcinfo.startAngle = 0; + arcinfo.endAngle = CIRCLE_IN_DEGREE; + + Style style; + style.lineColor_ = paint.GetStrokeColor(); + style.lineWidth_ = static_cast(paint.GetStrokeWidth()); + style.lineOpa_ = OPA_OPAQUE; + DrawArc::GetInstance()->Draw(arcinfo, invalidatedArea, style, OPA_OPAQUE, CapType::CAP_NONE); +} + +void UICanvas::DoDrawPath(void* param, + const Paint& paint, + const Rect& rect, + const Rect& invalidatedArea, + const Style& style) +{ + if (param == nullptr) { + return; + } + PathParam* pathParam = static_cast(param); + const UICanvasPath* path = pathParam->path; + if (path == nullptr) { + return; + } + Point pathEnd = {COORD_MIN, COORD_MIN}; + + ListNode* pointIter = path->points_.Begin(); + ListNode* arcIter = path->arcParam_.Begin(); + ListNode* iter = path->cmd_.Begin(); + for (uint16_t i = 0; (i < pathParam->count) && (iter != path->cmd_.End()); i++, iter = iter->next_) { + switch (iter->data_) { + case CMD_MOVE_TO: { + pointIter = pointIter->next_; + break; + } + case CMD_LINE_TO: { + Point start = pointIter->prev_->data_; + Point end = pointIter->data_; + pointIter = pointIter->next_; + if ((start.x == end.x) && (start.y == end.y)) { + break; + } + + GetAbsolutePosition(start, rect, style, start); + GetAbsolutePosition(end, rect, style, end); + DrawLine::Draw(start, end, invalidatedArea, paint.GetStrokeWidth(), paint.GetStrokeColor(), OPA_OPAQUE); + if ((pathEnd.x == start.x) && (pathEnd.y == start.y)) { + DoDrawLineJoin(start, invalidatedArea, paint); + } + pathEnd = end; + break; + } + case CMD_ARC: { + ArcInfo arcInfo = {{0}}; + arcInfo.imgPos = Point{0, 0}; + arcInfo.startAngle = arcIter->data_.startAngle; + arcInfo.endAngle = arcIter->data_.endAngle; + Style drawStyle = StyleDefault::GetDefaultStyle(); + drawStyle.lineWidth_ = static_cast(paint.GetStrokeWidth()); + drawStyle.lineColor_ = paint.GetStrokeColor(); + drawStyle.lineOpa_ = OPA_OPAQUE; + arcInfo.radius = arcIter->data_.radius + ((paint.GetStrokeWidth() + 1) >> 1); + + GetAbsolutePosition(arcIter->data_.center, rect, style, arcInfo.center); + DrawArc::GetInstance()->Draw(arcInfo, invalidatedArea, drawStyle, OPA_OPAQUE, CapType::CAP_NONE); + if (pointIter != path->points_.Begin()) { + DoDrawLineJoin(pathEnd, invalidatedArea, paint); + } + + GetAbsolutePosition(pointIter->data_, rect, style, pathEnd); + pointIter = pointIter->next_; + arcIter = arcIter->next_; + break; + } + case CMD_CLOSE: { + Point start = pointIter->prev_->data_; + Point end = pointIter->data_; + GetAbsolutePosition(start, rect, style, start); + GetAbsolutePosition(end, rect, style, end); + if ((start.x != end.x) || (start.y != end.y)) { + DrawLine::Draw(start, end, invalidatedArea, paint.GetStrokeWidth(), paint.GetStrokeColor(), + OPA_OPAQUE); + if ((pathEnd.x == start.x) && (pathEnd.y == start.y)) { + DoDrawLineJoin(start, invalidatedArea, paint); + } + pathEnd = end; + } + + if ((pathEnd.x == end.x) && (pathEnd.y == end.y)) { + DoDrawLineJoin(end, invalidatedArea, paint); + } + pointIter = pointIter->next_; + break; + } + default: + break; + } + } +} +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/components/ui_chart.cpp b/frameworks/components/ui_chart.cpp new file mode 100755 index 0000000..7542645 --- /dev/null +++ b/frameworks/components/ui_chart.cpp @@ -0,0 +1,832 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "components/ui_chart.h" +#include "draw/draw_arc.h" +#include "draw/draw_line.h" +#include "securec.h" + +namespace OHOS { +UIChart::~UIChart() +{ + if (mixData_ != nullptr) { + UIFree(mixData_); + mixData_ = nullptr; + } + ClearDataSerial(); + Remove(&xAxis_); + Remove(&yAxis_); +} + +void UIChart::SetHeight(int16_t height) +{ + if (GetHeight() == height) { + return; + } + + if (height > 0) { + needRefresh_ = true; + } + + UIViewGroup::SetHeight(height); + xAxis_.SetHeight(height); + xAxis_.UpdateAxis(); + yAxis_.SetHeight(height); + yAxis_.UpdateAxis(); +} + +void UIChart::SetWidth(int16_t width) +{ + UIViewGroup::SetWidth(width); + xAxis_.SetWidth(width); + yAxis_.SetWidth(width); + xAxis_.UpdateAxis(); + yAxis_.UpdateAxis(); +} + +void UIChart::OnDraw(const Rect& invalidatedArea) +{ + UIViewGroup::OnDraw(invalidatedArea); + Rect rect = GetContentRect(); + if (rect.Intersect(rect, invalidatedArea)) { + DrawDataSerials(rect); + } +} + +bool UIChart::AddDataSerial(UIChartDataSerial* dataSerial) +{ + if (dataSerial == nullptr) { + return false; + } + + ListNode* serialNode = list_.Head(); + while (serialNode != list_.End()) { + if (serialNode->data_ == dataSerial) { + return false; + } + serialNode = serialNode->next_; + } + list_.PushBack(dataSerial); + dataSerial->BindToChart(this); + return true; +} + +bool UIChart::DeleteDataSerial(UIChartDataSerial* dataSerial) +{ + if ((dataSerial == nullptr) || list_.IsEmpty()) { + return false; + } + + bool findSerial = false; + ListNode* serialNode = list_.Head(); + while (serialNode != list_.End()) { + if (serialNode->data_ == dataSerial) { + dataSerial->BindToChart(nullptr); + list_.Remove(serialNode); + findSerial = true; + break; + } + serialNode = serialNode->next_; + } + + return findSerial; +} + +void UIChart::ClearDataSerial() +{ + if (list_.IsEmpty()) { + return; + } + + ListNode* serialNode = list_.Head(); + while (serialNode != list_.End()) { + serialNode->data_->BindToChart(nullptr); + ListNode* tempNode = serialNode; + serialNode = serialNode->next_; + list_.Remove(tempNode); + } + list_.Clear(); +} + +UIChartDataSerial::UIChartDataSerial() + : maxCount_(0), + pointArray_(nullptr), + serialColor_(Color::White()), + fillColor_(Color::White()), + dataCount_(0), + peakPointIndex_(0), + peakData_(0), + valleyData_(0), + valleyPointIndex_(0), + lastPointIndex_(0), + latestIndex_(0), + hideIndex_(0), + hideCount_(0), + smooth_(false), + enableGradient_(false), + enableHeadPoint_(false), + enableTopPoint_(false), + enableBottomPoint_(false), + chart_(nullptr), + invalidateRect_(0, 0, 0, 0) +{ + PointStyle style; + style.radius = DEFAULT_POINT_RADIUS; + style.strokeWidth = 1; + style.fillColor = Color::White(); + style.strokeColor = Color::White(); + topPointStyle_ = style; + bottomPointStyle_ = style; + headPointStyle_ = style; +} + +bool UIChartDataSerial::SetMaxDataCount(uint16_t maxCount) +{ + if (maxCount > MAX_POINTS_COUNT) { + maxCount = MAX_POINTS_COUNT; + } + + if (maxCount == maxCount_) { + return true; + } + + if (pointArray_ != nullptr) { + UIFree(pointArray_); + pointArray_ = nullptr; + } + + maxCount_ = maxCount; + if (maxCount_ == 0) { + return true; + } + + pointArray_ = static_cast(UIMalloc(sizeof(Point) * maxCount_)); + if (pointArray_ == nullptr) { + maxCount_ = 0; + return false; + } + return true; +} + +bool UIChartDataSerial::ModifyPoint(uint16_t index, const Point& point) +{ + if ((index >= maxCount_) || (pointArray_ == nullptr)) { + return false; + } + + pointArray_[index].x = point.x; + pointArray_[index].y = point.y; + if (point.y > peakData_) { + if (enableTopPoint_) { + RefreshInvalidateRect(peakPointIndex_, topPointStyle_); + } + peakPointIndex_ = index; + peakData_ = point.y; + } else if (point.y < valleyData_) { + if (enableBottomPoint_) { + RefreshInvalidateRect(valleyPointIndex_, bottomPointStyle_); + } + valleyPointIndex_ = index; + valleyData_ = point.y; + } else if ((index == peakPointIndex_) || (index == valleyPointIndex_)) { + UpdatePeakAndValley(0, dataCount_); + } + + latestIndex_ = index; + uint16_t startIndex = (index == 0) ? index : (index - 1); + RefreshInvalidateRect(startIndex, index + 1); + return true; +} + +bool UIChartDataSerial::GetPoint(uint16_t index, Point& point) +{ + if ((index >= dataCount_) || (pointArray_ == nullptr)) { + return false; + } + point = pointArray_[index]; + if (chart_ != nullptr) { + chart_->GetXAxis().TranslateToPixel(point.x); + chart_->GetYAxis().TranslateToPixel(point.y); + } + return true; +} + +void UIChartDataSerial::HidePoint(uint16_t index, uint16_t count) +{ + hideIndex_ = index; + hideCount_ = count; + RefreshInvalidateRect(hideIndex_, hideIndex_ + hideCount_); +} + +void UIChartDataSerial::RefreshInvalidateRect(uint16_t pointIndex, const PointStyle& style) +{ + Point point; + if (GetPoint(pointIndex, point)) { + uint16_t width = style.radius + style.strokeWidth; + Rect refresh(point.x - width, 0, point.x + width, 0); + if ((invalidateRect_.GetLeft() == 0) && (invalidateRect_.GetRight() == 0)) { + invalidateRect_ = refresh; + } else { + invalidateRect_.Join(invalidateRect_, refresh); + } + } +} + +void UIChartDataSerial::RefreshInvalidateRect(uint16_t startIndex, uint16_t endIndex) +{ + Point start; + GetPoint(startIndex, start); + Point end; + endIndex = (endIndex >= dataCount_) ? (dataCount_ - 1) : endIndex; + GetPoint(endIndex, end); + int16_t xMin = MATH_MIN(start.x, end.x); + int16_t xMax = MATH_MAX(start.x, end.x); + Rect refresh(xMin, 0, xMax, 0); + if ((invalidateRect_.GetLeft() == 0) && (invalidateRect_.GetRight() == 0)) { + invalidateRect_ = refresh; + return; + } + invalidateRect_.Join(invalidateRect_, refresh); +} + +bool UIChartDataSerial::UpdatePeakAndValley(uint16_t startPos, uint16_t endPos) +{ + if ((startPos >= endPos) || (endPos > dataCount_) || (pointArray_ == nullptr)) { + return false; + } + + if (startPos == 0) { + peakData_ = pointArray_[startPos].y; + valleyData_ = pointArray_[startPos].y; + } + + for (uint16_t i = startPos; i < endPos; i++) { + if (pointArray_[i].y > peakData_) { + if (enableTopPoint_) { + RefreshInvalidateRect(peakPointIndex_, topPointStyle_); + RefreshInvalidateRect(i, topPointStyle_); + } + peakPointIndex_ = i; + peakData_ = pointArray_[i].y; + } + + if (pointArray_[i].y < valleyData_) { + if (enableBottomPoint_) { + RefreshInvalidateRect(valleyPointIndex_, bottomPointStyle_); + RefreshInvalidateRect(i, bottomPointStyle_); + } + valleyPointIndex_ = i; + valleyData_ = pointArray_[i].y; + } + } + return true; +} + +bool UIChartDataSerial::AddPoints(const Point* data, uint16_t count) +{ + if ((maxCount_ <= dataCount_) || (count == 0) || (pointArray_ == nullptr) || (data == nullptr)) { + return false; + } + + if (count > (maxCount_ - dataCount_)) { + count = maxCount_ - dataCount_; + } + + Point* current = pointArray_ + dataCount_; + if (memcpy_s(current, (maxCount_ - dataCount_) * sizeof(Point), data, count * sizeof(Point)) != EOK) { + return false; + } + uint16_t i = dataCount_; + dataCount_ += count; + UpdatePeakAndValley(i, dataCount_); + latestIndex_ = dataCount_ - 1; + uint16_t startIndex = (i == 0) ? i : (i - 1); + RefreshInvalidateRect(startIndex, latestIndex_); + return true; +} + +void UIChartDataSerial::ClearData() +{ + RefreshInvalidateRect(0, dataCount_ - 1); + if (pointArray_ != nullptr) { + if (memset_s(pointArray_, maxCount_ * sizeof(Point), 0, maxCount_ * sizeof(Point)) != EOK) { + return; + } + } + dataCount_ = 0; + valleyPointIndex_ = 0; + peakPointIndex_ = 0; + latestIndex_ = 0; +} + +void UIChartDataSerial::DoDrawPoint(const Point& center, const PointStyle& style, const Rect& mask) +{ + Style drawStyle = StyleDefault::GetDefaultStyle(); + drawStyle.lineOpa_ = OPA_OPAQUE; + drawStyle.lineColor_ = style.fillColor; + + ArcInfo arcinfo = {{0}}; + arcinfo.center = center; + arcinfo.imgPos = Point{0, 0}; + arcinfo.radius = style.radius + style.strokeWidth; + arcinfo.startAngle = 0; + arcinfo.endAngle = CIRCLE_IN_DEGREE; + + if (style.fillColor.full == style.strokeColor.full) { + drawStyle.lineWidth_ = style.radius + style.strokeWidth; + DrawArc::GetInstance()->Draw(arcinfo, mask, drawStyle, OPA_OPAQUE, CapType::CAP_NONE); + return; + } + drawStyle.lineWidth_ = style.radius; + arcinfo.radius = style.radius; + DrawArc::GetInstance()->Draw(arcinfo, mask, drawStyle, OPA_OPAQUE, CapType::CAP_NONE); + + drawStyle.lineWidth_ = style.strokeWidth; + drawStyle.lineColor_ = style.strokeColor; + arcinfo.radius = style.radius + style.strokeWidth; + DrawArc::GetInstance()->Draw(arcinfo, mask, drawStyle, OPA_OPAQUE, CapType::CAP_NONE); +} + +void UIChartDataSerial::DrawPoint(const Rect& mask) +{ + Point center; + if (enableTopPoint_) { + if (GetPoint(peakPointIndex_, center)) { + DoDrawPoint(center, topPointStyle_, mask); + } + } + + if (enableBottomPoint_) { + if (GetPoint(valleyPointIndex_, center)) { + DoDrawPoint(center, bottomPointStyle_, mask); + } + } + + if (enableHeadPoint_) { + if (GetPoint(latestIndex_, center)) { + DoDrawPoint(center, headPointStyle_, mask); + lastPointIndex_ = latestIndex_; + } + } +} + +void UIChartDataSerial::Refresh() +{ + if (chart_ != nullptr) { + Rect refresh = chart_->GetContentRect(); + refresh.SetLeft(invalidateRect_.GetLeft() - headPointStyle_.radius - headPointStyle_.strokeWidth); + refresh.SetRight(invalidateRect_.GetRight() + headPointStyle_.radius + headPointStyle_.strokeWidth); + invalidateRect_.SetRect(0, 0, 0, 0); + chart_->InvalidateRect(refresh); + + if (enableHeadPoint_ && (lastPointIndex_ != latestIndex_)) { + RefreshInvalidateRect(lastPointIndex_, headPointStyle_); + refresh.SetLeft(invalidateRect_.GetLeft()); + refresh.SetRight(invalidateRect_.GetRight()); + chart_->InvalidateRect(refresh); + invalidateRect_.SetRect(0, 0, 0, 0); + } + } +} + +void UIChartPillar::RefreshChart() +{ + ListNode* iter = list_.Begin(); + Rect rect = GetContentRect(); + for (; iter != list_.End(); iter = iter->next_) { + UIChartDataSerial* data = iter->data_; + if (data == nullptr) { + break; + } + uint16_t dataCount = data->GetDataCount(); + if (dataCount <= 1) { + break; + } + + uint16_t index = data->GetLastPointIndex(); + if (index >= dataCount) { + break; + } + + Point current; + data->GetPoint(index, current); + Point last; + data->GetPoint(dataCount - 1, last); + Rect refresh(current.x, rect.GetTop(), last.x, rect.GetBottom()); + InvalidateRect(refresh); + data->SetLastPointIndex(dataCount - 1); + } +} + +void UIChartPillar::DrawDataSerials(const Rect& invalidatedArea) +{ + xAxis_.UpdateAxisPoints(); + yAxis_.UpdateAxisPoints(); + uint16_t minXStep = static_cast(xAxis_.GetMarkInterval()); + Point xStart = xAxis_.GetStartPoint(); + uint16_t dataSerialCount = list_.Size(); + if (dataSerialCount == 0) { + return; + } + uint16_t width = minXStep / dataSerialCount; + uint8_t dataSerialIndex = 0; + uint16_t barWidth = static_cast(width - DEFAULT_MARK_PERCENTAGE * (width << 1)); + + for (ListNode* iter = list_.Begin(); iter != list_.End(); iter = iter->next_) { + UIChartDataSerial* data = iter->data_; + uint16_t dataSerialWidth = width * dataSerialIndex; + int16_t x = dataSerialWidth + (width >> 1); + for (uint16_t index = 0; index < data->GetDataCount(); index++) { + Point current; + data->GetPoint(index, current); + if (current.y == xStart.y) { + continue; + } + current.x += x; + xStart.x = current.x; + DrawLine::Draw(current, xStart, invalidatedArea, barWidth, data->GetFillColor(), style_->lineOpa_); + } + dataSerialIndex++; + } +} + +void UIChartPolyline::RefreshChart() +{ + ListNode* iter = list_.Begin(); + for (; iter != list_.End(); iter = iter->next_) { + UIChartDataSerial* data = iter->data_; + uint16_t dataCount = data->GetDataCount(); + if (dataCount == 1) { + break; + } + data->Refresh(); + } +} + +void UIChartPolyline::ReMeasure() +{ + if (!needRefresh_) { + return; + } + needRefresh_ = false; + int16_t height = GetHeight(); + if (mixData_ != nullptr) { + UIFree(mixData_); + mixData_ = nullptr; + } + if (height <= 0) { + return; + } + if (height > COORD_MAX) { + height = COORD_MAX; + } + mixData_ = static_cast(UIMalloc(height)); + if (mixData_ == nullptr) { + return; + } + int16_t opa = maxOpa_ - minOpa_; + for (int16_t y = 0; y < height; y++) { + mixData_[y] = static_cast(y * opa / height + minOpa_); + } +} + +void UIChartPolyline::DrawDataSerials(const Rect& invalidatedArea) +{ + xAxis_.UpdateAxisPoints(); + yAxis_.UpdateAxisPoints(); + ListNode* iter = list_.Begin(); + for (; iter != list_.End(); iter = iter->next_) { + UIChartDataSerial* data = iter->data_; + uint16_t dataCount = data->GetDataCount(); + if (dataCount <= 1) { + continue; + } + if (data->IsGradient()) { + GradientColor(invalidatedArea, data); + } + if (data->GetHideCount() != 0) { + uint16_t hideIndex = data->GetHideIndex(); + DrawPolyLine(0, hideIndex, invalidatedArea, data); + DrawPolyLine(hideIndex + data->GetHideCount(), dataCount - 1, invalidatedArea, data); + } else { + DrawPolyLine(0, dataCount - 1, invalidatedArea, data); + } + + data->DrawPoint(invalidatedArea); + } +} + +void UIChartPolyline::DrawSmoothPolyLine(uint16_t startIndex, + uint16_t endIndex, + const Rect& invalidatedArea, + UIChartDataSerial* data) +{ + if (data == nullptr) { + return; + } + Point start; + Point end; + ColorType color = data->GetLineColor(); + Style style = *style_; + style.lineColor_ = color; + style.lineOpa_ = OPA_OPAQUE; + + uint16_t slope; + data->GetPoint(startIndex, start); + data->GetPoint(startIndex + 1, end); + uint16_t preSlope = (start.x == end.x) ? QUARTER_IN_DEGREE : FastAtan2(end.x - start.x, end.y - start.y); + Point current; + for (uint16_t i = startIndex; i < endIndex; i++) { + data->GetPoint(i + 1, current); + if (((end.y - start.y <= 0) && (current.y - end.y <= 0)) || + ((end.y - start.y >= 0) && (current.y - end.y >= 0))) { + slope = (current.x == start.x) ? QUARTER_IN_DEGREE : FastAtan2(current.x - start.x, current.y - start.y); + if (MATH_ABS(slope - preSlope) < SMOOTH_SLOPE_ANGLE) { + end = current; + continue; + } + } + preSlope = (current.x == end.x) ? QUARTER_IN_DEGREE : FastAtan2(current.x - end.x, current.y - end.y); + Rect rect; + rect.SetLeft(MATH_MIN(start.x, end.x) - style_->lineWidth_); + rect.SetRight(MATH_MAX(start.x, end.x) + style_->lineWidth_); + rect.SetTop(MATH_MIN(start.y, end.y) - style_->lineWidth_); + rect.SetBottom(MATH_MAX(start.y, end.y) + style_->lineWidth_); + if (!invalidatedArea.IsIntersect(rect)) { + start = end; + end = current; + continue; + } + + DrawLine::Draw(start, end, invalidatedArea, style_->lineWidth_, color, OPA_OPAQUE); + ArcInfo arcinfo = {{0}}; + arcinfo.center = end; + arcinfo.imgPos = Point{0, 0}; + arcinfo.radius = (style_->lineWidth_ + 1) >> 1; + arcinfo.startAngle = 0; + arcinfo.endAngle = CIRCLE_IN_DEGREE; + + DrawArc::GetInstance()->Draw(arcinfo, invalidatedArea, style, OPA_OPAQUE, CapType::CAP_NONE); + + start = end; + end = current; + } + DrawLine::Draw(start, end, invalidatedArea, style_->lineWidth_, color, OPA_OPAQUE); +} + +void UIChartPolyline::DrawPolyLine(uint16_t startIndex, + uint16_t endIndex, + const Rect& invalidatedArea, + UIChartDataSerial* data) +{ + if ((startIndex >= endIndex) || (data == nullptr)) { + return; + } + + if (data->IsSmooth()) { + DrawSmoothPolyLine(startIndex, endIndex, invalidatedArea, data); + return; + } + Point start; + Point end; + ColorType color = data->GetLineColor(); + Style style = *style_; + style.lineColor_ = color; + style.lineOpa_ = OPA_OPAQUE; + ArcInfo arcinfo = {{0}}; + arcinfo.imgPos = Point{0, 0}; + arcinfo.radius = (style_->lineWidth_ + 1) >> 1; + arcinfo.startAngle = 0; + arcinfo.endAngle = CIRCLE_IN_DEGREE; + for (uint16_t i = startIndex; i < endIndex - 1; i++) { + data->GetPoint(i, start); + data->GetPoint(i + 1, end); + Rect rect; + rect.SetLeft(MATH_MIN(start.x, end.x) - style_->lineWidth_); + rect.SetRight(MATH_MAX(start.x, end.x) + style_->lineWidth_); + rect.SetTop(MATH_MIN(start.y, end.y) - style_->lineWidth_); + rect.SetBottom(MATH_MAX(start.y, end.y) + style_->lineWidth_); + if (!invalidatedArea.IsIntersect(rect)) { + continue; + } + + DrawLine::Draw(start, end, invalidatedArea, style_->lineWidth_, color, OPA_OPAQUE); + if (style_->lineWidth_ >= LINE_JOIN_WIDTH) { + arcinfo.center = end; + DrawArc::GetInstance()->Draw(arcinfo, invalidatedArea, style, OPA_OPAQUE, CapType::CAP_NONE); + } + } + data->GetPoint(endIndex - 1, start); + data->GetPoint(endIndex, end); + DrawLine::Draw(start, end, invalidatedArea, style_->lineWidth_, color, OPA_OPAQUE); +} + +bool UIChartPolyline::GetLineCrossPoint(const Point& p1, + const Point& p2, + const Point& p3, + const Point& p4, + Point& cross) +{ + /* Rectangular ranges of line segments must intersect. */ + if ((MATH_MIN(p1.x, p2.x) <= MATH_MAX(p3.x, p4.x)) && (MATH_MIN(p3.x, p4.x) <= MATH_MAX(p1.x, p2.x)) && + (MATH_MIN(p1.y, p2.y) <= MATH_MAX(p3.y, p4.y)) && (MATH_MIN(p3.y, p4.y) <= MATH_MAX(p1.y, p2.y))) { + /* Check whether the lines are parallel. If the lines are collinear, there is no intersection point. */ + if ((p4.y - p3.y) * (p2.x - p1.x) - (p4.x - p3.x) * (p2.y - p1.y) != 0) { + /* + * (y1 - y2)x + (x2 - x1)y = x2y1 - x1y2 -> ax + by = c + * (y3 - y4)x + (x4 - x3)y = x4y3 - x3y4 -> dx + ey = f + */ + int64_t a = p1.y - p2.y; + int64_t b = p2.x - p1.x; + int64_t c = p2.x * p1.y - p1.x * p2.y; + int64_t d = p3.y - p4.y; + int64_t e = p4.x - p3.x; + int64_t f = p4.x * p3.y - p3.x * p4.y; + int64_t left = a * e - b * d; + int64_t right = c * e - b * f; + if (left == 0) { + return false; + } + cross.x = static_cast(right / left); + left = b * d - a * e; + right = c * d - a * f; + if (left == 0) { + return false; + } + cross.y = static_cast(right / left); + if ((cross.x >= MATH_MIN(p1.x, p2.x)) && (cross.x <= MATH_MAX(p1.x, p2.x)) && + (cross.x >= MATH_MIN(p3.x, p4.x)) && (cross.x <= MATH_MAX(p3.x, p4.x))) { + return true; + } + } + } + return false; +} + +void UIChartPolyline::FindCrossPoints(const ChartLine& line, const ChartLine& polyLine, CrossPointSet& cross) +{ + if (GetLineCrossPoint(line.start, line.end, polyLine.start, polyLine.end, cross.nextFirst)) { + if (!cross.firstFind) { + /* first corss must on the line like "/" */ + if (polyLine.start.y < polyLine.end.y) { + cross.first = cross.nextFirst; + cross.firstFind = true; + } + } else if (!cross.secondFind) { + /* second corss can't be same with first cross. */ + if ((cross.first.x != cross.nextFirst.x) || (cross.first.y != cross.nextFirst.y)) { + cross.second = cross.nextFirst; + cross.secondFind = true; + return; + } + /* second corss must on the line like "\", otherwise skip those crosss. */ + if (polyLine.start.y > polyLine.end.y) { + cross.firstFind = false; + } + } + } +} + +void UIChartPolyline::DrawGradientColor(const Rect& invalidatedArea, + UIChartDataSerial* data, + const ChartLine& linePoints, + const ChartLine& limitPoints, + int16_t startY) +{ + if (data == nullptr) { + return; + } + Rect currentRect = GetContentRect(); + CrossPointSet cross = {{0}}; + ChartLine polyLine = {{0}}; + uint16_t pointCount = data->GetDataCount() - 1; + int16_t y = enableReverse_ ? (linePoints.start.y + startY) : (startY - linePoints.start.y); + int16_t mixScale = !enableReverse_ ? (currentRect.GetBottom() - y) : (y - currentRect.GetTop()); + if ((mixScale < 0) || (mixScale >= currentRect.GetHeight())) { + return; + } + bool onVerticalLine = enableReverse_ ? (y <= limitPoints.start.y) : (y >= limitPoints.start.y); + if (onVerticalLine) { + cross.first.x = limitPoints.start.x; + cross.first.y = enableReverse_ ? (y - startY) : (startY - y); + cross.firstFind = true; + } + + Point start; + Point end; + for (uint16_t i = 0; i < pointCount; i++) { + data->GetPoint(i, start); + data->GetPoint(i + 1, end); + if (start.y == end.y) { + int16_t tmpY = enableReverse_ ? (start.y + startY) : (startY - start.y); + if (tmpY == linePoints.start.y) { + cross.firstFind = false; + cross.secondFind = false; + } + continue; + } + start.y = enableReverse_ ? (start.y - startY) : (startY - start.y); + end.y = enableReverse_ ? (end.y - startY) : (startY - end.y); + polyLine.start = start; + polyLine.end = end; + FindCrossPoints(linePoints, polyLine, cross); + if (cross.firstFind && cross.secondFind) { + cross.first.y = enableReverse_ ? (cross.first.y + startY) : (startY - cross.first.y); + cross.second.y = enableReverse_ ? (cross.second.y + startY) : (startY - cross.second.y); + DrawLine::Draw(cross.first, cross.second, invalidatedArea, 1, data->GetFillColor(), mixData_[mixScale]); + cross.firstFind = false; + cross.secondFind = false; + } + } + + if (cross.firstFind && !cross.secondFind) { + cross.second.x = limitPoints.end.x; + cross.second.y = y; + cross.first.y = y; + DrawLine::Draw(cross.first, cross.second, invalidatedArea, 1, data->GetFillColor(), mixData_[mixScale]); + } +} + +void UIChartPolyline::CalcVerticalInfo(int16_t top, + int16_t bottom, + int16_t start, + int16_t end, + int16_t& y, + int16_t& yHeight) +{ + if ((top < start) && (bottom > start)) { + y = start; + yHeight = top; + } else if ((bottom <= start) && (top >= end)) { + y = bottom; + yHeight = top; + } else if ((top < end) && (bottom > end)) { + y = bottom; + yHeight = end; + } +} + +void UIChartPolyline::GradientColor(const Rect& invalidatedArea, UIChartDataSerial* data) +{ + if (data == nullptr) { + return; + } + int16_t bottom = invalidatedArea.GetBottom(); + int16_t top = invalidatedArea.GetTop(); + Point yStart = yAxis_.GetStartPoint(); + yStart.y = enableReverse_ ? (yStart.y + gradientBottom_) : (yStart.y - gradientBottom_); + int16_t topY = enableReverse_ ? data->GetValleyData() : data->GetPeakData(); + int16_t bottomY = enableReverse_ ? data->GetPeakData() : data->GetValleyData(); + yAxis_.TranslateToPixel(topY); + yAxis_.TranslateToPixel(bottomY); + int16_t valleyY = enableReverse_ ? topY : bottomY; + int16_t startY = enableReverse_ ? topY : yStart.y; + int16_t endY = enableReverse_ ? yStart.y : topY; + if ((bottom < endY) || (top > startY)) { + return; + } + + int16_t y = 0; + int16_t yHeight = 0; + CalcVerticalInfo(top, bottom, startY, endY, y, yHeight); + + ChartLine limitPoints = {{0}}; + data->GetPoint(0, limitPoints.start); + data->GetPoint(data->GetDataCount() - 1, limitPoints.end); + ChartLine linePoints = {{0}}; + linePoints.start.x = limitPoints.start.x; + linePoints.end.x = limitPoints.end.x; + Rect currentRect = GetContentRect(); + while (y >= yHeight) { + linePoints.start.y = enableReverse_ ? (y - endY) : (startY - y); + linePoints.end.y = linePoints.start.y; + if (y <= valleyY) { + int16_t baseY = enableReverse_ ? endY : startY; + DrawGradientColor(invalidatedArea, data, linePoints, limitPoints, baseY); + } else { + int16_t mixScale = enableReverse_ ? (linePoints.start.y + endY - currentRect.GetTop()) : + (currentRect.GetBottom() - (startY - linePoints.start.y)); + if ((mixScale < 0) || (mixScale >= currentRect.GetHeight())) { + y--; + continue; + } + Point start = {limitPoints.start.x, y}; + Point end = {limitPoints.end.x, y}; + DrawLine::Draw(start, end, invalidatedArea, 1, data->GetFillColor(), mixData_[mixScale]); + } + y--; + } +} +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/components/ui_checkbox.cpp b/frameworks/components/ui_checkbox.cpp new file mode 100755 index 0000000..aed4c14 --- /dev/null +++ b/frameworks/components/ui_checkbox.cpp @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "common/image.h" +#include "components/ui_checkbox.h" +#include "default_resource/check_box_res.h" +#include "draw/draw_image.h" +#include "draw/draw_rect.h" +#include "imgdecode/cache_manager.h" + +namespace OHOS { +UICheckBox::UICheckBox() + : state_(UNSELECTED), onStateChangeListener_(nullptr) +{ + touchable_ = true; + style_ = &(StyleDefault::GetBackgroundTransparentStyle()); + image_[UNSELECTED].SetSrc(GetCheckBoxOffInfo()); + image_[SELECTED].SetSrc(GetCheckBoxOnInfo()); + ImageHeader header = { 0 }; + image_[UNSELECTED].GetHeader(header); + Resize(header.width, header.height); +} + +UICheckBox::~UICheckBox() +{ +} + +void UICheckBox::SetState(UICheckBoxState state) +{ + if (state != state_) { + state_ = state; + if (onStateChangeListener_ != nullptr) { + onStateChangeListener_->OnChange(state); + } + Invalidate(); + } +} + +void UICheckBox::ReverseState() +{ + state_ = (state_ == SELECTED) ? UNSELECTED : SELECTED; +} + +bool UICheckBox::OnClickEvent(const ClickEvent& event) +{ + ReverseState(); + Invalidate(); + return UIView::OnClickEvent(event); +} + +void UICheckBox::SetImages(const char* selectedImageSrc, const char* unselectedImageSrc) +{ + image_[SELECTED].SetSrc(selectedImageSrc); + image_[UNSELECTED].SetSrc(unselectedImageSrc); +} + +void UICheckBox::SetImages(const ImageInfo* selectedImageSrc, const ImageInfo* unselectedImageSrc) +{ + image_[SELECTED].SetSrc(selectedImageSrc); + image_[UNSELECTED].SetSrc(unselectedImageSrc); +} + +void UICheckBox::OnDraw(const Rect& invalidatedArea) +{ + ImageHeader header = {0}; + image_[state_].GetHeader(header); + int16_t imgWidth = header.width; + int16_t imgHeight = header.height; + Rect coords = GetContentRect(); + coords.SetWidth(imgWidth); + coords.SetHeight(imgHeight); + DrawRect::Draw(GetRect(), invalidatedArea, *style_, opaScale_); + + int16_t offsetLeft = (GetWidth() - imgWidth) / 2; // 2 : half + int16_t offsetTop = (GetHeight() - imgHeight) / 2; // 2 : half + coords.SetX(coords.GetX() + offsetLeft); + coords.SetY(coords.GetY() + offsetTop); + Rect trunc = invalidatedArea; + if (trunc.Intersect(trunc, coords)) { + image_[state_].DrawImage(coords, trunc, *style_, opaScale_); + } +} +} // namespace OHOS diff --git a/frameworks/components/ui_circle_progress.cpp b/frameworks/components/ui_circle_progress.cpp new file mode 100755 index 0000000..59a2ec0 --- /dev/null +++ b/frameworks/components/ui_circle_progress.cpp @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "components/ui_circle_progress.h" +#include "draw/draw_arc.h" +#include "draw/draw_line.h" +#include "draw/draw_rect.h" + +namespace OHOS { +UICircleProgress::UICircleProgress() + : center_({0, 0}), + backgroundImagePos_({0, 0}), + progressImagePos_({0, 0}), + radius_(0), + startAngle_(MIN_ANGLE_VALUE), + endAngle_(MAX_ANGLE_VALUE) +{ +} + +void UICircleProgress::SetCenterPosition(int16_t x, int16_t y) +{ + center_.x = x; + center_.y = y; +} + +void UICircleProgress::SetStartAngle(int16_t startAngle) +{ + startAngle_ = startAngle; +} + +void UICircleProgress::SetEndAngle(int16_t endAngle) +{ + endAngle_ = endAngle; +} + +void UICircleProgress::GetStartEndAngle(int16_t& start, int16_t& end) const +{ + if (startAngle_ > endAngle_) { + start = endAngle_; + end = startAngle_; + } else { + start = startAngle_; + end = endAngle_; + } +} + +void UICircleProgress::GetAngleRange(int16_t& start, int16_t& end) const +{ + GetStartEndAngle(start, end); + DrawArc::GetInstance()->GetDrawRange(start, end); +} + +void UICircleProgress::GetRedrawAngle(int16_t& start, int16_t& end) const +{ + GetStartEndAngle(start, end); + + if (startAngle_ == endAngle_) { + return; + } + + int16_t angleRange = end - start; + angleRange = (angleRange > CIRCLE_IN_DEGREE) ? CIRCLE_IN_DEGREE : angleRange; + + int16_t angle = GetCurrentPos(angleRange); + if (startAngle_ > endAngle_) { + start = end - angle; + } else { + end = angle + start; + } + DrawArc::GetInstance()->GetDrawRange(start, end); +} + +void UICircleProgress::DrawCommonCircle(const Rect& invalidatedArea) +{ + ArcInfo arcinfo = {{0}}; + arcinfo.radius = radius_; + int16_t endAngle; + int16_t startAngle; + GetRedrawAngle(startAngle, endAngle); + + int16_t start; + int16_t end; + GetAngleRange(start, end); + Rect rect = GetOrigRect(); + arcinfo.center.x = center_.x + rect.GetLeft() + style_->paddingLeft_ + style_->borderWidth_; + arcinfo.center.y = center_.y + rect.GetTop() + style_->paddingTop_ + style_->borderWidth_; + + if (enableBackground_ && ((start != end) || (backgroundStyle_->lineCap_ == CapType::CAP_ROUND))) { + arcinfo.imgPos.x = backgroundImagePos_.x + rect.GetLeft(); + arcinfo.imgPos.y = backgroundImagePos_.y + rect.GetTop(); + arcinfo.startAngle = start; + arcinfo.endAngle = end; + arcinfo.imgSrc = backgroundImage_; + DrawArc::GetInstance()->Draw(arcinfo, invalidatedArea, *backgroundStyle_, opaScale_, + backgroundStyle_->lineCap_); + } + + if ((startAngle != endAngle) || (foregroundStyle_->lineCap_ == CapType::CAP_ROUND)) { + arcinfo.imgPos.x = progressImagePos_.x + rect.GetLeft(); + arcinfo.imgPos.y = progressImagePos_.y + rect.GetTop(); + arcinfo.startAngle = startAngle; + arcinfo.endAngle = endAngle; + arcinfo.imgSrc = foregroundImage_; + DrawArc::GetInstance()->Draw(arcinfo, invalidatedArea, *foregroundStyle_, opaScale_, + foregroundStyle_->lineCap_); + } +} + +void UICircleProgress::OnDraw(const Rect& invalidatedArea) +{ + if (GetRangeSize() == 0) { + return; + } + + DrawRect::Draw(GetOrigRect(), invalidatedArea, *style_, opaScale_); + + Rect trunc(invalidatedArea); + if (trunc.Intersect(trunc, GetOrigRect())) { + DrawCommonCircle(trunc); + } +} +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/components/ui_dialog.cpp b/frameworks/components/ui_dialog.cpp new file mode 100755 index 0000000..8bb8d5b --- /dev/null +++ b/frameworks/components/ui_dialog.cpp @@ -0,0 +1,694 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "components/ui_dialog.h" +#include "common/screen.h" +#include "common/typed_text.h" +#if ENABLE_DEBUG +#include "graphic_assert.h" +#endif +#include "graphic_log.h" +#if ENABLE_WINDOW +#include "window/window.h" +#endif + +#if ENABLE_WINDOW +namespace OHOS { +class UIDialogLabelButton : public UILabelButton { +public: + UIDialogLabelButton(UIDialog* dialog) + { + dialog_ = dialog; + } + virtual ~UIDialogLabelButton() {} + virtual bool OnClickEvent(const ClickEvent& event) + { + bool ret = true; + if (dialog_ != nullptr) { + dialog_->DestoryWindow(); + dialog_->isShowing_ = false; + } + if (onClickListener_ != nullptr) { + ret = onClickListener_->OnClick(*this, event); + } + return ret; + } +private: + UIDialog* dialog_; +}; + +class UIDialogClickListener : public UIView::OnClickListener { +public: + UIDialogClickListener(UIDialog* dialog) + { + dialog_ = dialog; + } + virtual ~UIDialogClickListener() {} + bool OnClick(UIView& view, const ClickEvent& event) override + { + bool ret = true; + if ((dialog_ != nullptr) && (dialog_->dialogLayer_ != nullptr) && + !dialog_->dialogLayer_->GetRect().IsContains(event.GetCurrentPos())) { + if (dialog_->enableAutoCancel_) { + dialog_->DestoryWindow(); + dialog_->isShowing_ = false; + } + if (dialog_->onCancelListener_ != nullptr) { + ret = dialog_->onCancelListener_->OnClick(view, event); + } + } + return ret; + } +private: + UIDialog* dialog_; +}; + +UIDialog::UIDialog() + : isShowing_(false), + enableAutoCancel_(false), + buttonNum_(0), + title_(nullptr), + text_(nullptr), + button1_(nullptr), + button2_(nullptr), + button3_(nullptr), + dialogLayer_(nullptr), + windowRootView_(nullptr), + onCancelListener_(nullptr), + dialogClickListener_(nullptr), + window_(nullptr), + line1_(nullptr), + line2_(nullptr), + titleText_(nullptr), + textText_(nullptr) +{ + uint16_t screenWidth = Screen::GetInstance().GetWidth(); + uint16_t screenHeight = Screen::GetInstance().GetHeight(); + // 100: calculate percentage + widthMax_ = screenWidth * MAX_WIDTH_PERCENT / 100; + // 100: calculate percentage + heightMax_ = screenHeight * MAX_HEIGHT_PERCENT / 100; + colorType1_ = Color::White(); + colorType2_ = Color::White(); + colorType3_ = Color::White(); +} + +UIDialog::~UIDialog() +{ + onCancelListener_ = nullptr; + if (dialogLayer_ != nullptr) { + dialogLayer_->RemoveAll(); + delete dialogLayer_; + dialogLayer_ = nullptr; + } + if (title_ != nullptr) { + delete title_; + title_ = nullptr; + } + if (text_ != nullptr) { + delete text_; + text_ = nullptr; + } + if (button1_ != nullptr) { + delete button1_; + button1_ = nullptr; + } + if (button2_ != nullptr) { + delete button2_; + button2_ = nullptr; + } + if (button3_ != nullptr) { + delete button3_; + button3_ = nullptr; + } + if (line1_ != nullptr) { + delete line1_; + line1_ = nullptr; + } + if (line2_ != nullptr) { + delete line2_; + line2_ = nullptr; + } + if ((windowRootView_ != nullptr) && !RootView::DestoryWindowRootView(windowRootView_)) { + windowRootView_ = nullptr; + } + if (dialogClickListener_ != nullptr) { + delete dialogClickListener_; + dialogClickListener_ = nullptr; + } +} + +void UIDialog::SetTitle(const char* title) +{ + if (title == nullptr) { + return; + } + titleText_ = title; +} + +void UIDialog::SetText(const char* text) +{ + if (text == nullptr) { + return; + } + textText_ = text; +} + +void UIDialog::SetButton(DialogButtonType buttonType, const char* text, UIView::OnClickListener* listener) +{ + switch (buttonType) { + case DialogButtonType::BUTTON_LEFT: + if (button1_ == nullptr) { + button1_ = new UIDialogLabelButton(this); + if (button1_ == nullptr) { + GRAPHIC_LOGE("new UIDialogLabelButton fail"); + return; + } + button1_->SetViewId(BUTTON1_ID); + AddButton(buttonType, button1_, text, listener); + } else { + button1_->SetText(text); + button1_->SetOnClickListener(listener); + } + break; + case DialogButtonType::BUTTON_MID: + if (button2_ == nullptr) { + button2_ = new UIDialogLabelButton(this); + if (button2_ == nullptr) { + GRAPHIC_LOGE("new UIDialogLabelButton fail"); + return; + } + button2_->SetViewId(BUTTON2_ID); + AddButton(buttonType, button2_, text, listener); + } else { + button2_->SetText(text); + button2_->SetOnClickListener(listener); + } + break; + case DialogButtonType::BUTTON_RIGHT: + if (button3_ == nullptr) { + button3_ = new UIDialogLabelButton(this); + if (button3_ == nullptr) { + GRAPHIC_LOGE("new UIDialogLabelButton fail"); + return; + } + AddButton(buttonType, button3_, text, listener); + } else { + button3_->SetText(text); + button3_->SetOnClickListener(listener); + } + break; + default: + break; + } +} + +void UIDialog::AddButton(DialogButtonType buttonType, + UILabelButton* button, + const char* text, + UIView::OnClickListener* listener) +{ + buttonNum_++; + button->SetText(text); + button->SetOnClickListener(listener); + button->SetFont(DEFAULT_VECTOR_FONT_FILENAME, BUTTON_FONT_SIZE); + button->SetTextColor(Color::Blue()); + button->SetStyleForState(STYLE_BACKGROUND_COLOR, Color::White().full, UIButton::ButtonState::RELEASED); + button->SetStyleForState(STYLE_BACKGROUND_COLOR, Color::Black().full, UIButton::ButtonState::PRESSED); + button->SetStyleForState(STYLE_BACKGROUND_OPA, BUTTON_PRESS_OPA, UIButton::ButtonState::PRESSED); + button->SetStyleForState(STYLE_BORDER_WIDTH, 0, UIButton::ButtonState::RELEASED); + button->SetStyleForState(STYLE_BORDER_WIDTH, 0, UIButton::ButtonState::PRESSED); + button->SetHeight(BUTTON_HEIGHT); +} + +void UIDialog::Show() +{ + if (isShowing_) { + return; + } + SetTitleLabel(); + SetTextLabel(); + InitDialog(); + AddComponents(); + MeasureSize(); + Layout(); + CreateDialogWindow(); + window_->Show(); + isShowing_ = true; +} + +void UIDialog::SetTitleLabel() +{ + if (titleText_ == nullptr) { + return; + } + if (title_ == nullptr) { + title_ = new UILabel(); + if (title_ == nullptr) { + GRAPHIC_LOGE("new UILabel fail"); + return; + } + title_->SetViewId(TITLE_ID); + title_->SetFont(DEFAULT_VECTOR_FONT_FILENAME, TITLE_FONT_SIZE); + title_->SetAlign(UITextLanguageAlignment::TEXT_ALIGNMENT_LEFT); + title_->SetStyle(STYLE_TEXT_COLOR, Color::Black().full); + title_->SetStyle(STYLE_TEXT_OPA, TITLE_TEXT_OPA); + title_->SetStyle(STYLE_BACKGROUND_COLOR, Color::White().full); + } + title_->SetText(titleText_); +} + +void UIDialog::SetTextLabel() +{ + if (textText_ == nullptr) { + return; + } + if (text_ == nullptr) { + text_ = new UILabel(); + if (text_ == nullptr) { + GRAPHIC_LOGE("new UILabel fail"); + return; + } + text_->SetFont(DEFAULT_VECTOR_FONT_FILENAME, TEXT_FONT_SIZE); + text_->SetStyle(STYLE_TEXT_COLOR, Color::Black().full); + text_->SetStyle(STYLE_TEXT_OPA, TITLE_TEXT_OPA); + text_->SetStyle(STYLE_BACKGROUND_COLOR, Color::White().full); + } + text_->SetText(textText_); +} + +void UIDialog::InitDialog() +{ + if (dialogLayer_ == nullptr) { + dialogLayer_ = new UIViewGroup(); + if (dialogLayer_ == nullptr) { + GRAPHIC_LOGE("new UIViewGroup fail"); + return; + } + dialogLayer_->SetStyle(STYLE_BACKGROUND_COLOR, Color::White().full); + } + if (windowRootView_ == nullptr) { + windowRootView_ = RootView::GetWindowRootView(); + windowRootView_->SetWidth(Screen::GetInstance().GetWidth()); + windowRootView_->SetHeight(Screen::GetInstance().GetHeight()); + windowRootView_->SetTouchable(true); + windowRootView_->Add(dialogLayer_); + } + if (dialogClickListener_ == nullptr) { + dialogClickListener_ = new UIDialogClickListener(this); + if (dialogClickListener_ == nullptr) { + GRAPHIC_LOGE("new UIDialogClickListener fail"); + return; + } + windowRootView_->SetOnClickListener(dialogClickListener_); + } +} + +void UIDialog::AddComponents() +{ + if (title_ != nullptr) { + dialogLayer_->Add(title_); + } + if (text_ != nullptr) { + dialogLayer_->Add(text_); + } + if (button1_ != nullptr) { + dialogLayer_->Add(button1_); + } + if (button2_ != nullptr) { + dialogLayer_->Add(button2_); + } + if (button3_ != nullptr) { + dialogLayer_->Add(button3_); + } + if (buttonNum_ > 1) { + line1_ = new UIView(); + if (line1_ == nullptr) { + GRAPHIC_LOGE("new UIView fail"); + return; + } + line1_->SetHeight(LINE_HEIGHT); + line1_->SetWidth(LINE_WIDTH); + line1_->SetStyle(STYLE_BACKGROUND_COLOR, Color::Black().full); + line1_->SetStyle(STYLE_BACKGROUND_OPA, LINE_OPA); + dialogLayer_->Add(line1_); + } + if (buttonNum_ == 3) { // 3: three buttons + line2_ = new UIView(); + if (line2_ == nullptr) { + GRAPHIC_LOGE("new UIView fail"); + return; + } + line2_->SetHeight(LINE_HEIGHT); + line2_->SetWidth(LINE_WIDTH); + line2_->SetStyle(STYLE_BACKGROUND_COLOR, Color::Black().full); + line2_->SetStyle(STYLE_BACKGROUND_OPA, LINE_OPA); + dialogLayer_->Add(line2_); + } +} + +void UIDialog::MeasureSize() +{ + uint16_t width = MeasureMaxWidth(); + uint16_t height = 0; + + if (buttonNum_ > 0) { + // 2: there are 2 paddings horizontally + uint16_t buttonWidth = (width - 2 * BUTTON_PADDING - (buttonNum_ - 1) * BUTTON_MID_PADDING) / buttonNum_; + // 2: there are 2 paddings horizontally + width = static_cast(buttonWidth) * buttonNum_ + (buttonNum_ - 1) * BUTTON_MID_PADDING + + 2 * BUTTON_PADDING; + height += BUTTON_TOTAL_HEIGHT; + height += TEXT_BUTTON_PADDING; + if (button1_ != nullptr) { + button1_->SetWidth(buttonWidth); + } + if (button2_ != nullptr) { + button2_->SetWidth(buttonWidth); + } + if (button3_ != nullptr) { + button3_->SetWidth(buttonWidth); + } + } else { + height += PADDING; + } + + if (title_ != nullptr) { + title_->SetWidth(width - 2 * PADDING); // 2: there are 2 paddings horizontally + height += TITLE_TOTAL_HEIGHT; + } else { + height += PADDING; + } + + if (text_ != nullptr) { + text_->SetWidth(width - 2 * PADDING); // 2: there are 2 paddings horizontally + uint16_t textHightMax = heightMax_ - height; + if (text_->GetTextHeight() < textHightMax) { + text_->SetHeight(text_->GetTextHeight()); + } else { + text_->SetHeight(textHightMax); + text_->SetLineBreakMode(UILabel::LINE_BREAK_ELLIPSIS); + } + height += text_->GetHeight(); + } + + uint16_t dialogHeight = height; + dialogLayer_->SetHeight(dialogHeight); + dialogLayer_->SetWidth(width); +} + +uint16_t UIDialog::MeasureMaxWidth() +{ + uint16_t titleWidth = 0; + uint16_t textWidth = 0; + uint16_t buttonTotalWidth = 0; + + if (title_ != nullptr) { + titleWidth = MeasureTitleWidth(); + titleWidth += 2 * PADDING; // 2: there are 2 paddings horizontally + } + if (text_ != nullptr) { + textWidth = MeasureTextWidth(); + textWidth += 2 * PADDING; // 2: there are 2 paddings horizontally + } + if (buttonNum_ > 0) { + buttonTotalWidth = + static_cast(MeasureButtonWidth()) * buttonNum_ + (buttonNum_ - 1) * BUTTON_MID_PADDING; + buttonTotalWidth += 2 * BUTTON_PADDING; // 2: there are 2 paddings horizontally + } + return MATH_MAX(titleWidth, MATH_MAX(textWidth, buttonTotalWidth)); +} + +uint16_t UIDialog::MeasureTitleWidth() +{ + uint16_t titleWidth = 0; + uint16_t widthMaxNoPadding = widthMax_ - 2 * PADDING; // 2: there are 2 paddings horizontally + title_->SetLineBreakMode(UILabel::LINE_BREAK_ADAPT); + if (title_->GetTextWidth() > widthMaxNoPadding) { + titleWidth = widthMaxNoPadding; + title_->SetLineBreakMode(UILabel::LINE_BREAK_ELLIPSIS); + } else { + titleWidth = title_->GetTextWidth(); + } + title_->SetHeight(title_->GetTextHeight()); + return titleWidth; +} + +uint16_t UIDialog::MeasureTextWidth() +{ + uint16_t textWidth = 0; + uint16_t widthMaxNoPadding = widthMax_ - 2 * PADDING; // 2: there are 2 paddings horizontally + if (title_ != nullptr) { + text_->SetAlign(UITextLanguageAlignment::TEXT_ALIGNMENT_LEFT); + } else { + text_->SetAlign(UITextLanguageAlignment::TEXT_ALIGNMENT_CENTER); + } + text_->SetLineBreakMode(UILabel::LINE_BREAK_ADAPT); + textWidth = text_->GetTextWidth(); + if (text_->GetTextWidth() > widthMaxNoPadding) { + text_->SetAlign(UITextLanguageAlignment::TEXT_ALIGNMENT_LEFT); + textWidth = widthMaxNoPadding; + text_->SetLineBreakMode(UILabel::LINE_BREAK_WRAP); + } + return textWidth; +} + +uint16_t UIDialog::MeasureButtonWidth() +{ + if (buttonNum_ == 0) { + return 0; + } + + uint16_t buttonTextWidth = 0; + // 2: there are 2 paddings horizontally + uint16_t buttonMaxWidth = (widthMax_ - 2 * BUTTON_PADDING - (buttonNum_ - 1) * BUTTON_MID_PADDING) / buttonNum_; + + if (button1_ != nullptr) { + const char* text1 = button1_->GetText(); + buttonTextWidth = MATH_MAX(buttonTextWidth, TypedText::GetTextSize(text1, + button1_->GetStyleConst().letterSpace_, button1_->GetStyleConst().lineSpace_, widthMax_).x); + } + if (button2_ != nullptr) { + const char* text2 = button2_->GetText(); + buttonTextWidth = MATH_MAX(buttonTextWidth, TypedText::GetTextSize(text2, + button2_->GetStyleConst().letterSpace_, button2_->GetStyleConst().lineSpace_, widthMax_).x); + } + if (button3_ != nullptr) { + const char* text3 = button3_->GetText(); + buttonTextWidth = MATH_MAX(buttonTextWidth, TypedText::GetTextSize(text3, + button3_->GetStyleConst().letterSpace_, button3_->GetStyleConst().lineSpace_, widthMax_).x); + } + return (buttonTextWidth + BUTTON_HEIGHT) > buttonMaxWidth ? buttonMaxWidth : (buttonTextWidth + BUTTON_HEIGHT); +} + +void UIDialog::Layout() +{ + if (title_ != nullptr) { + // 2: there are 2 paddings vertically + uint8_t padding = (TITLE_TOTAL_HEIGHT - title_->GetHeight()) / 2; + title_->LayoutLeftOfParent(PADDING); + title_->LayoutTopOfParent(padding); + if (text_ != nullptr) { + text_->LayoutLeftOfParent(PADDING); + text_->LayoutBottomToSibling(TITLE_ID, padding); + } + } else { + if (text_ != nullptr) { + text_->LayoutLeftOfParent(PADDING); + text_->LayoutTopOfParent(PADDING); + } + } + LayoutButton(); +} + +void UIDialog::LayoutButton() +{ + if (button1_ != nullptr) { + button1_->LayoutLeftOfParent(BUTTON_PADDING); + button1_->LayoutBottomOfParent(BUTTON_PADDING); + if (button2_ != nullptr) { + button2_->LayoutRightToSibling(BUTTON1_ID, BUTTON_MID_PADDING); + button2_->LayoutBottomOfParent(BUTTON_PADDING); + } + } else if (button2_ != nullptr) { + button2_->LayoutLeftOfParent(BUTTON_PADDING); + button2_->LayoutBottomOfParent(BUTTON_PADDING); + } + if (button3_ != nullptr) { + button3_->LayoutRightOfParent(BUTTON_PADDING); + button3_->LayoutBottomOfParent(BUTTON_PADDING); + } + + if (buttonNum_ == 3) { // 3: three buttons + line1_->LayoutBottomOfParent(LINE_BOTTOM_PADDING); + line1_->LayoutRightToSibling(BUTTON1_ID, LINE_BUTTON_PADDING); + line2_->LayoutBottomOfParent(LINE_BOTTOM_PADDING); + line2_->LayoutRightToSibling(BUTTON2_ID, LINE_BUTTON_PADDING); + } else if (buttonNum_ == 2) { // 2: two buttons + if (button1_ != nullptr) { + line1_->LayoutBottomOfParent(LINE_BOTTOM_PADDING); + line1_->LayoutRightToSibling(BUTTON1_ID, LINE_BUTTON_PADDING); + } else { + line1_->LayoutBottomOfParent(LINE_BOTTOM_PADDING); + line1_->LayoutRightToSibling(BUTTON2_ID, LINE_BUTTON_PADDING); + } + } +} + +void UIDialog::CreateDialogWindow() +{ + dialogLayer_->LayoutCenterOfParent(); + Rect rect = dialogLayer_->GetRect(); + int16_t offset_x = dialogLayer_->GetX(); + int16_t offset_y = dialogLayer_->GetY(); + + windowRootView_->SetPosition(-offset_x, -offset_y); + windowRootView_->Invalidate(); + + WindowConfig config = {}; + config.rect = rect; + config.rect.SetPosition(offset_x, offset_y); + config.isModal = true; + window_ = Window::CreateWindow(config); + if (window_ != nullptr) { + window_->BindRootView(windowRootView_); + } else { + GRAPHIC_LOGE("Create window false!"); + } +} + +void UIDialog::SetButtonColor(DialogButtonType buttonType, ColorType color) +{ + switch (buttonType) { + case DialogButtonType::BUTTON_LEFT: + if (button1_ != nullptr) { + button1_->SetStyleForState(STYLE_BACKGROUND_COLOR, color.full, UIButton::ButtonState::RELEASED); + button1_->SetStyleForState(STYLE_BACKGROUND_OPA, color.alpha, UIButton::ButtonState::RELEASED); + colorType1_ = color; + } + break; + case DialogButtonType::BUTTON_MID: + if (button2_ != nullptr) { + button2_->SetStyleForState(STYLE_BACKGROUND_COLOR, color.full, UIButton::ButtonState::RELEASED); + button2_->SetStyleForState(STYLE_BACKGROUND_OPA, color.alpha, UIButton::ButtonState::RELEASED); + colorType2_ = color; + } + break; + case DialogButtonType::BUTTON_RIGHT: + if (button3_ != nullptr) { + button3_->SetStyleForState(STYLE_BACKGROUND_COLOR, color.full, UIButton::ButtonState::RELEASED); + button3_->SetStyleForState(STYLE_BACKGROUND_COLOR, color.alpha, UIButton::ButtonState::RELEASED); + colorType3_ = color; + } + break; + default: + break; + } +} + +void UIDialog::SetOnCancelListener(UIView::OnClickListener* onCancelListener) +{ + if (onCancelListener == nullptr) { + return; + } + onCancelListener_ = onCancelListener; +} + +void UIDialog::EnableAutoCancel(bool enable) +{ + enableAutoCancel_ = enable; +} + +void UIDialog::DestoryWindow() +{ + if (window_ != nullptr) { + Window::DestoryWindow(window_); + window_ = nullptr; + } +} + +#ifdef ENABLE_DEBUG +const char* UIDialog::GetButtonText(DialogButtonType buttonType) const +{ + switch (buttonType) { + case DialogButtonType::BUTTON_LEFT: + if (button1_ != nullptr) { + return button1_->GetText(); + } + return nullptr; + case DialogButtonType::BUTTON_MID: + if (button2_ != nullptr) { + return button2_->GetText(); + } + return nullptr; + case DialogButtonType::BUTTON_RIGHT: + if (button3_ != nullptr) { + return button3_->GetText(); + } + return nullptr; + default: + return nullptr; + } +} + +UIView::OnClickListener* UIDialog::GetButtonListener(DialogButtonType buttonType) const +{ + switch (buttonType) { + case DialogButtonType::BUTTON_LEFT: + if (button1_ != nullptr) { + return button1_->GetOnClickListener(); + } + return nullptr; + case DialogButtonType::BUTTON_MID: + if (button2_ != nullptr) { + return button2_->GetOnClickListener(); + } + return nullptr; + case DialogButtonType::BUTTON_RIGHT: + if (button3_ != nullptr) { + return button3_->GetOnClickListener(); + } + return nullptr; + default: + return nullptr; + } +} + +ColorType UIDialog::GetButtonColor(DialogButtonType buttonType) const +{ + switch (buttonType) { + case DialogButtonType::BUTTON_LEFT: + if (button1_ != nullptr) { + return colorType1_; + } + break; + case DialogButtonType::BUTTON_MID: + if (button2_ != nullptr) { + return colorType2_; + } + break; + case DialogButtonType::BUTTON_RIGHT: + if (button3_ != nullptr) { + return colorType3_; + } + break; + default: + break; + } + ASSERT(0); +} +#endif // ENABLE_DEBUG +} // namespace OHOS +#endif // ENABLE_WINDOW \ No newline at end of file diff --git a/frameworks/components/ui_digital_clock.cpp b/frameworks/components/ui_digital_clock.cpp new file mode 100755 index 0000000..406c5f7 --- /dev/null +++ b/frameworks/components/ui_digital_clock.cpp @@ -0,0 +1,249 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "components/ui_digital_clock.h" +#include +#include "components/ui_view_group.h" +#include "font/ui_font.h" +#include "graphic_log.h" +#include "securec.h" + +namespace OHOS { +UIDigitalClock::UIDigitalClock() + : timeLabels_{0}, + displayMode_(DISPLAY_24_HOUR), + leadingZero_(true), + color_(Color::White()), + prevHour_(0), + prevMinute_(0), + prevSecond_(0), + verticalShow_(false) +{ + style_ = &(StyleDefault::GetBackgroundTransparentStyle()); +} + +void UIDigitalClock::InitTimeLabels() +{ + for (uint8_t i = 0; i < TIME_ELEMENT_COUNT; i++) { + if (timeLabels_[i] == nullptr) { + timeLabels_[i] = new UILabel; + if (timeLabels_[i] == nullptr) { + GRAPHIC_LOGE("new UILabel fail"); + return; + } + timeLabels_[i]->SetLineBreakMode(UILabel::LINE_BREAK_ADAPT); + timeLabels_[i]->SetStyle(STYLE_BACKGROUND_OPA, OPA_TRANSPARENT); + Add(timeLabels_[i]); + } + } +} + +void UIDigitalClock::DisplayLeadingZero(bool displayLeadingZero) +{ + leadingZero_ = displayLeadingZero; + UpdateClock(false); +} + +void UIDigitalClock::SetOpacity(uint8_t opacity) +{ + opaScale_ = opacity; + InitTimeLabels(); + for (uint8_t i = 0; i < TIME_ELEMENT_COUNT; i++) { + timeLabels_[i]->SetStyle(STYLE_TEXT_OPA, opacity); + } + RefreshTime(); +} + +uint8_t UIDigitalClock::GetOpacity() const +{ + return opaScale_; +} + +void UIDigitalClock::SetFontId(uint8_t fontId) +{ + SetStyle(STYLE_TEXT_FONT, fontId); + InitTimeLabels(); + for (uint8_t i = 0; i < TIME_ELEMENT_COUNT; i++) { + timeLabels_[i]->SetFontId(fontId); + } + UpdateClock(false); +} + +void UIDigitalClock::SetFont(const char* name, uint8_t size) +{ + InitTimeLabels(); + for (uint8_t i = 0; i < TIME_ELEMENT_COUNT; i++) { + timeLabels_[i]->SetFont(name, size); + } + UpdateClock(false); +} + +void UIDigitalClock::SetColor(ColorType color) +{ + color_ = color; + InitTimeLabels(); + for (uint8_t i = 0; i < TIME_ELEMENT_COUNT; i++) { + timeLabels_[i]->SetStyle(STYLE_TEXT_COLOR, color.full); + } + RefreshTime(); +} + +void UIDigitalClock::TimeElementRefresh() +{ + InitTimeLabels(); + if (currentHour_ != prevHour_) { + prevHour_ = currentHour_; + timeLabels_[HOUR_ELEMENT]->Invalidate(); + } + + if (currentMinute_ != prevMinute_) { + prevMinute_ = currentMinute_; + timeLabels_[MINUTE_ELEMENT]->Invalidate(); + } + + if (currentSecond_ != prevSecond_) { + prevSecond_ = currentSecond_; + timeLabels_[SECOND_ELEMENT]->Invalidate(); + } +} + +void UIDigitalClock::RefreshTime() +{ + InitTimeLabels(); + for (uint8_t i = 0; i < TIME_ELEMENT_COUNT; i++) { + timeLabels_[i]->Invalidate(); + } +} + +void UIDigitalClock::UpdateClock(bool clockInit) +{ + char buf[TIME_ELEMENT_COUNT][BUFFER_SIZE] = {{0}}; + const char* formatWithColon = leadingZero_ ? "%02d:" : "%d:"; + const char* formatWithoutColon = leadingZero_ ? "%02d" : "%d"; + const char* format = verticalShow_ ? formatWithoutColon : formatWithColon; + const char* formatForMinute = verticalShow_ ? "%02d" : "%02d:"; + switch (displayMode_) { + case DISPLAY_24_HOUR_NO_SECONDS: { + if (sprintf_s(buf[HOUR_ELEMENT], BUFFER_SIZE, format, currentHour_) < 0) { + return; + } + if (sprintf_s(buf[MINUTE_ELEMENT], BUFFER_SIZE, "%02d", currentMinute_) < 0) { + return; + } + break; + } + case DISPLAY_12_HOUR_NO_SECONDS: { + if (sprintf_s(buf[HOUR_ELEMENT], BUFFER_SIZE, format, currentHour_ % HALF_DAY_IN_HOUR) < 0) { + return; + } + if (sprintf_s(buf[MINUTE_ELEMENT], BUFFER_SIZE, "%02d", currentMinute_) < 0) { + return; + } + break; + } + case DISPLAY_12_HOUR: { + if (sprintf_s(buf[HOUR_ELEMENT], BUFFER_SIZE, format, currentHour_ % HALF_DAY_IN_HOUR) < 0) { + return; + } + if (sprintf_s(buf[MINUTE_ELEMENT], BUFFER_SIZE, formatForMinute, currentMinute_) < 0) { + return; + } + if (sprintf_s(buf[SECOND_ELEMENT], BUFFER_SIZE, "%02d", currentSecond_) < 0) { + return; + } + break; + } + case DISPLAY_24_HOUR: { + if (sprintf_s(buf[HOUR_ELEMENT], BUFFER_SIZE, format, currentHour_) < 0) { + return; + } + if (sprintf_s(buf[MINUTE_ELEMENT], BUFFER_SIZE, formatForMinute, currentMinute_) < 0) { + return; + } + if (sprintf_s(buf[SECOND_ELEMENT], BUFFER_SIZE, "%02d", currentSecond_) < 0) { + return; + } + break; + } + default: { + break; + } + } + SetTimeLabels(buf); +} + +void UIDigitalClock::SetTimeLabels(const char buf[TIME_ELEMENT_COUNT][BUFFER_SIZE]) +{ + InitTimeLabels(); + for (uint8_t i = 0; i < TIME_ELEMENT_COUNT; i++) { + timeLabels_[i]->SetText(buf[i]); + } + + SetTimeLabelsPosition(); + TimeElementRefresh(); +} + +void UIDigitalClock::SetHorizontal() +{ + InitTimeLabels(); + uint16_t totalWidth = timeLabels_[HOUR_ELEMENT]->GetWidth() + timeLabels_[MINUTE_ELEMENT]->GetWidth() + + timeLabels_[SECOND_ELEMENT]->GetWidth(); + UITextLanguageAlignment align = timeLabels_[HOUR_ELEMENT]->GetHorAlign(); + int16_t x = 0; + Rect rect = GetContentRect(); + if (align == TEXT_ALIGNMENT_CENTER) { + x = (rect.GetWidth() >> 1) - (totalWidth >> 1); + } else if (align == TEXT_ALIGNMENT_RIGHT) { + x = rect.GetRight() - totalWidth; + } + timeLabels_[HOUR_ELEMENT]->SetPosition(x, 0); + int16_t width = timeLabels_[HOUR_ELEMENT]->GetWidth(); + for (uint8_t i = 1; i < TIME_ELEMENT_COUNT; i++) { + timeLabels_[i]->SetPosition(x + width, 0); + width += timeLabels_[i]->GetWidth(); + } +} + +void UIDigitalClock::SetTimeLabelsPosition() +{ + if (verticalShow_) { + SetVertical(); + } else { + SetHorizontal(); + } +} + +void UIDigitalClock::SetVertical() +{ + InitTimeLabels(); + int16_t fontHeight = timeLabels_[HOUR_ELEMENT]->GetHeight(); + timeLabels_[HOUR_ELEMENT]->SetPosition(0, 0); + int16_t y = fontHeight; + for (uint8_t i = 1; i < TIME_ELEMENT_COUNT; i++) { + timeLabels_[i]->SetPosition(0, y); + y += fontHeight; + } +} + +UIDigitalClock::~UIDigitalClock() +{ + for (uint8_t i = 0; i < TIME_ELEMENT_COUNT; i++) { + if (timeLabels_[i] != nullptr) { + delete timeLabels_[i]; + timeLabels_[i] = nullptr; + } + } +} +} // namespace OHOS diff --git a/frameworks/components/ui_image_animator.cpp b/frameworks/components/ui_image_animator.cpp new file mode 100755 index 0000000..2882e41 --- /dev/null +++ b/frameworks/components/ui_image_animator.cpp @@ -0,0 +1,204 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "components/ui_image_animator.h" + +namespace OHOS { +UIImageAnimatorView::UIImageAnimatorView() + : imageSrc_(nullptr), imageNum_(0), tickOfUpdate_(1), timeOfUpdate_(DEFAULT_TASK_PERIOD), + timeOfPause_(0), tickOfPause_(0), repeatTimes_(1), imageAnimator_(&imageAnimatorCallback_, this, 0, true), + listener_(nullptr), reverse_(false), repeat_(true), sizeFixed_(false), fillMode_(true) +{ + AnimatorManager::GetInstance()->Add(&imageAnimator_); +} + +UIImageAnimatorView::~UIImageAnimatorView() +{ + AnimatorManager::GetInstance()->Remove(&imageAnimator_); +} + +void UIImageAnimatorView::ImageAnimatorCallback::Callback(UIView* view) +{ + if (view == nullptr) { + return; + } + UIImageAnimatorView* imageAnimatorView = static_cast(view); + + imageSrc_ = imageAnimatorView->GetImageAnimatorSrc(); + imageNum_ = imageAnimatorView->GetImageAnimatorImageNum(); + if ((imageSrc_ == nullptr) || (imageNum_ == 0) || (imageAnimatorView->tickOfUpdate_ == 0)) { + return; + } + + if (!imageAnimatorView->IsRepeat() && (repeat_ == imageAnimatorView->GetRepeatTimes())) { + imageAnimatorView->Stop(); + return; + } + + tickNum_++; + + if (loop_ != imageNum_) { + if (tickNum_ < imageAnimatorView->tickOfUpdate_) { + return; + } + } else { + if (imageAnimatorView->tickOfPause_ != 0) { + if (tickNum_ < imageAnimatorView->tickOfPause_) { + return; + } + } else { + if (tickNum_ < imageAnimatorView->tickOfUpdate_) { + return; + } + } + repeat_++; + loop_ = 0; + if (!imageAnimatorView->IsRepeat() && (repeat_ == imageAnimatorView->GetRepeatTimes())) { + imageAnimatorView->Stop(); + return; + } + } + imageAnimatorView->UpdateImage(drawingImage_, loop_); + tickNum_ = 0; +} + +void UIImageAnimatorView::UpdateImage(uint8_t& drawingImage, uint8_t& loop) +{ + Invalidate(); + drawingImage = reverse_ ? (imageNum_ - loop - 1) : loop; + if (drawingImage >= imageNum_) { + return; + } + + ImageAnimatorInfo* imageAnimatorInfo = &(imageSrc_[drawingImage]); + if (imageAnimatorInfo->imageType == IMG_SRC_FILE_PATH) { + SetSrc(imageAnimatorInfo->imagePath); + } else if (imageAnimatorInfo->imageType == IMG_SRC_IMAGE_INFO) { + SetSrc(imageAnimatorInfo->imageInfo); + } + if (!sizeFixed_) { + SetPosition(imageAnimatorInfo->pos.x, imageAnimatorInfo->pos.y); + SetWidth(imageAnimatorInfo->width); + SetHeight(imageAnimatorInfo->height); + } + Invalidate(); + loop++; +} + +void UIImageAnimatorView::SetImageAnimatorSrc(const ImageAnimatorInfo imageAnimatorInfoSrc[], uint8_t imageNum) +{ + SetImageAnimatorSrc(imageAnimatorInfoSrc, imageNum, timeOfUpdate_); +} + +void UIImageAnimatorView::SetImageAnimatorSrc(const ImageAnimatorInfo imageAnimatorInfoSrc[], + uint8_t imageNum, uint16_t timeOfUpdate) +{ + imageSrc_ = const_cast(imageAnimatorInfoSrc); + imageNum_ = imageNum; + timeOfUpdate_ = timeOfUpdate; + tickOfUpdate_ = GetTickByTime(timeOfUpdate); + return; +} + +const ImageAnimatorInfo* UIImageAnimatorView::GetImageAnimatorSrc() const +{ + return imageSrc_; +} + +uint8_t UIImageAnimatorView::GetImageAnimatorImageNum() const +{ + return imageNum_; +} + +void UIImageAnimatorView::SetTimeOfUpdate(uint16_t timeOfUpdate) +{ + timeOfUpdate_ = timeOfUpdate; + tickOfUpdate_ = GetTickByTime(timeOfUpdate); +} + +uint16_t UIImageAnimatorView::GetTimeOfUpdate() const +{ + return timeOfUpdate_; +} + +void UIImageAnimatorView::SetTimeOfPause(uint16_t timeOfPause) +{ + timeOfPause_ = timeOfPause; + tickOfPause_ = GetTickByTime(timeOfPause); +} + +uint16_t UIImageAnimatorView::GetTimeOfPause() const +{ + return timeOfPause_; +} + +void UIImageAnimatorView::Start() +{ + Reset(false); + imageAnimator_.SetState(Animator::START); +} + +void UIImageAnimatorView::Reset(bool fillMode) +{ + if ((imageSrc_ == nullptr) || (imageNum_ == 0)) { + return; + } + + Invalidate(); + uint8_t drawingImage; + if (fillMode) { + drawingImage = reverse_ ? 0 : (imageNum_ - 1); + } else { + drawingImage = reverse_ ? (imageNum_ - 1) : 0; + } + ImageAnimatorInfo* imageAnimatorInfo = &(imageSrc_[drawingImage]); + if (imageAnimatorInfo->imageType == IMG_SRC_FILE_PATH) { + SetSrc(imageAnimatorInfo->imagePath); + } else if (imageAnimatorInfo->imageType == IMG_SRC_IMAGE_INFO) { + SetSrc(imageAnimatorInfo->imageInfo); + } + if (!sizeFixed_) { + SetPosition(imageAnimatorInfo->pos.x, imageAnimatorInfo->pos.y); + SetWidth(imageAnimatorInfo->width); + SetHeight(imageAnimatorInfo->height); + } + Invalidate(); + imageAnimatorCallback_.Reset(); +} + +void UIImageAnimatorView::Stop() +{ + if (imageAnimator_.GetState() == Animator::STOP) { + return; + } + + imageAnimator_.SetState(Animator::STOP); + Reset(fillMode_); + if (listener_ != nullptr) { + listener_->OnAnimatorStop(*this); + } +} + +uint8_t UIImageAnimatorView::GetTickByTime(uint16_t time) const +{ + uint8_t tick; + if ((time > 0) && (time <= DEFAULT_TASK_PERIOD)) { + tick = 1; + } else { + tick = time / DEFAULT_TASK_PERIOD; + } + return tick; +} +} diff --git a/frameworks/components/ui_image_view.cpp b/frameworks/components/ui_image_view.cpp new file mode 100755 index 0000000..2fdd403 --- /dev/null +++ b/frameworks/components/ui_image_view.cpp @@ -0,0 +1,424 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "components/ui_image_view.h" +#include "common/image.h" +#include "common/typed_text.h" +#include "draw/draw_image.h" +#include "draw/draw_label.h" +#include "draw/draw_rect.h" +#include "file.h" +#include "image_info.h" +#include "imgdecode/cache_manager.h" +#include "mem_api.h" +#ifndef VERSION_LITE +#include "gif_lib.h" +#endif + +namespace OHOS { +#ifndef VERSION_LITE +class GifImageAnimator : public Animator, public AnimatorCallback { +public: + GifImageAnimator(UIView* view, const char* src) + : Animator(this, view, 0, true), + gifFileType_(nullptr), + imageIndex_(0), + delayTime_(0), + lastRunTime_(0), + deltaTime_(0), + gifDataSize_(0), + src_(src) + { + } + + virtual ~GifImageAnimator() + { + CloseGifFile(); + } + + void Callback(UIView* view) override; + + void SetGifFileType(GifFileType* gifFileType) + { + gifFileType_ = gifFileType; + } + + uint32_t SetGifFrame(GifFileType* gifFileType, int32_t imageIndex, UIImageView* imageView) const; + void DealGifImageData(const GifFileType* gifFileType, + const GifImageDesc* gifImageDesc, + const SavedImage* savedImage, + GraphicsControlBlock gcb, + const ColorMapObject* colorMap) const; + const void OpenGifFile(const char* src); + void CloseGifFile(); + +private: + GifFileType* GetGifFileType() + { + if (gifFileType_ == nullptr) { + OpenGifFile(src_); + } + return gifFileType_; + } + + GifFileType* gifFileType_; + int32_t imageIndex_; + uint32_t delayTime_; + uint32_t lastRunTime_; + uint32_t deltaTime_; + uint32_t gifDataSize_; + uint8_t* gifImageData_ = nullptr; + const char* src_; +}; + +const void GifImageAnimator::OpenGifFile(const char* src) +{ + int32_t error = D_GIF_SUCCEEDED; + GifFileType* gifFileType = DGifOpenFileName(src, &error); + if (error != D_GIF_SUCCEEDED) { + return; + } + DGifSlurp(gifFileType); + /* 3 : when change single pixel to byte, the buffer should divided by 8, equal to shift right 3 bits. */ + uint8_t pixelByteSize = DrawUtils::GetPxSizeByColorMode(ARGB8888) >> 3; + gifDataSize_ = gifFileType->SWidth * gifFileType->SHeight * pixelByteSize; + gifImageData_ = static_cast(UIMalloc(gifDataSize_)); + if (gifImageData_ == nullptr) { + CloseGifFile(); + return; + } + SetGifFileType(gifFileType); +} + +void GifImageAnimator::CloseGifFile() +{ + GifFileType* gifFileType = GetGifFileType(); + if (gifFileType != nullptr) { + DGifCloseFile(gifFileType, nullptr); + } + if (gifImageData_ != nullptr) { + UIFree(reinterpret_cast(const_cast(gifImageData_))); + gifImageData_ = nullptr; + } +} + +void GifImageAnimator::Callback(UIView* view) +{ + if (view == nullptr) { + return; + } + UIImageView* imageView = static_cast(view); + uint32_t curTime = GetRunTime(); + if (curTime != 0) { + if (curTime + deltaTime_ - lastRunTime_ >= delayTime_) { + deltaTime_ = curTime + deltaTime_ - lastRunTime_ - delayTime_; + lastRunTime_ = curTime; + } else { + return; + } + } + GifFileType* gifFileType = GetGifFileType(); + if (gifFileType != nullptr) { + delayTime_ = SetGifFrame(gifFileType, imageIndex_, imageView); + imageIndex_ = (imageIndex_ < gifFileType->ImageCount - 1) ? (imageIndex_ + 1) : 0; + } +} + +uint32_t GifImageAnimator::SetGifFrame(GifFileType* gifFileType, int32_t imageIndex, UIImageView* imageView) const +{ + SavedImage* savedImage = &(gifFileType->SavedImages[imageIndex]); + if (savedImage == nullptr) { + return 0; + } + GifImageDesc* gifImageDesc = &(savedImage->ImageDesc); + if (gifImageDesc == nullptr) { + return 0; + } + GraphicsControlBlock gcb; + int32_t ret = DGifSavedExtensionToGCB(gifFileType, imageIndex, &gcb); + if (ret != GIF_OK) { + return 0; + } + ColorMapObject* colorMap = nullptr; + if (gifImageDesc->ColorMap != nullptr) { + colorMap = gifImageDesc->ColorMap; + } else { + colorMap = gifFileType->SColorMap; + } + + DealGifImageData(gifFileType, gifImageDesc, savedImage, gcb, colorMap); + if (gifImageData_ == nullptr) { + return 0; + } + imageView->gifFrameFlag_ = true; + ImageInfo gifFrame; + gifFrame.header.width = gifFileType->SWidth; + gifFrame.header.height = gifFileType->SHeight; + gifFrame.header.colorMode = ARGB8888; + gifFrame.dataSize = gifDataSize_; + gifFrame.data = gifImageData_; + imageView->SetSrc(&gifFrame); + + if (gcb.DelayTime >= 0) { + return static_cast(gcb.DelayTime) * 10; // 10: change hundredths (1/100) of a second to millisecond + } else { + return 0; + } +} + +void GifImageAnimator::DealGifImageData(const GifFileType* gifFileType, + const GifImageDesc* gifImageDesc, + const SavedImage* savedImage, + GraphicsControlBlock gcb, + const ColorMapObject* colorMap) const +{ + if ((gifFileType == nullptr) || (gifImageDesc == nullptr) || (savedImage == nullptr) || + (savedImage->RasterBits == nullptr) || (colorMap == nullptr) || (colorMap->Colors == nullptr)) { + return; + } + uint8_t colorIndex = 0; + GifColorType* gifColorType = nullptr; + uint32_t index = 0; + bool transparentColor = true; + int32_t loc = 0; + for (int32_t x = 0; x < gifFileType->SHeight; x++) { + for (int32_t y = 0; y < gifFileType->SWidth; y++) { + transparentColor = true; + if ((x >= gifImageDesc->Top) && (x < gifImageDesc->Top + gifImageDesc->Height) && + (y >= gifImageDesc->Left) && (y < gifImageDesc->Left + gifImageDesc->Width)) { + loc = (x - gifImageDesc->Top) * gifImageDesc->Width + (y - gifImageDesc->Left); + colorIndex = savedImage->RasterBits[loc]; + + if ((gcb.DisposalMode != DISPOSE_DO_NOT) || (gcb.TransparentColor == NO_TRANSPARENT_COLOR) || + (colorIndex != gcb.TransparentColor)) { + transparentColor = false; + } + } + if (transparentColor) { + index += 4; // 4: skip color index, keep last frame color + } else { + gifColorType = &colorMap->Colors[colorIndex]; + gifImageData_[index++] = gifColorType->Blue; + gifImageData_[index++] = gifColorType->Green; + gifImageData_[index++] = gifColorType->Red; + gifImageData_[index++] = OPA_OPAQUE; + } + } + } +} +#endif + +UIImageView::UIImageView() + : imageWidth_(0), + imageHeight_(0), + autoEnable_(true), + needRefresh_(false), + colorFormat_(UNKNOW), + blurLevel_(BlurLevel::LEVEL0), + algorithm_(TransformAlgorithm::BILINEAR), + reserve_(0) +{ + style_ = &(StyleDefault::GetBackgroundTransparentStyle()); +#ifndef VERSION_LITE + gifImageAnimator_ = nullptr; + gifFrameFlag_ = false; +#endif +} + +UIImageView::~UIImageView() +{ +#ifndef VERSION_LITE + RemoveAndStopGifAnimator(); +#endif +} + +bool UIImageView::OnPreDraw(Rect& invalidatedArea) const +{ + if ((image_.GetSrcType() == IMG_SRC_UNKNOWN)) { + return true; + } + + if ((colorFormat_ == RGB565) || (colorFormat_ == RGB888)) { + if (GetRect().IsContains(invalidatedArea)) { + return true; + } + invalidatedArea.Intersect(invalidatedArea, GetRect()); + } + + return false; +} + +void UIImageView::OnDraw(const Rect& invalidatedArea) +{ + OpacityType opa = GetMixOpaScale(); + DrawRect::Draw(GetRect(), invalidatedArea, *style_, opa); + if ((imageHeight_ == 0) || (imageWidth_ == 0)) { + return; + } + + Rect viewRect = GetContentRect(); + Rect trunc(invalidatedArea); + if (trunc.Intersect(trunc, viewRect)) { + uint8_t srcType = image_.GetSrcType(); + if ((srcType == IMG_SRC_FILE) || (srcType == IMG_SRC_VARIABLE)) { + Rect cordsTmp; + cordsTmp.SetTop(viewRect.GetY()); + cordsTmp.SetBottom(viewRect.GetY() + imageHeight_ - 1); + + if ((transMap_ == nullptr) || transMap_->IsInvalid()) { + while (cordsTmp.GetTop() <= viewRect.GetBottom()) { + cordsTmp.SetLeft(viewRect.GetX()); + cordsTmp.SetRight(viewRect.GetX() + imageWidth_ - 1); + while (cordsTmp.GetLeft() <= viewRect.GetRight()) { + image_.DrawImage(cordsTmp, trunc, *style_, opa); + cordsTmp.SetLeft(cordsTmp.GetLeft() + imageWidth_); + cordsTmp.SetRight(cordsTmp.GetRight() + imageWidth_); + } + cordsTmp.SetTop(cordsTmp.GetTop() + imageHeight_); + cordsTmp.SetBottom(cordsTmp.GetBottom() + imageHeight_); + } + } else if ((transMap_ != nullptr) && !transMap_->IsInvalid()) { + ImageInfo imgInfo; + if (srcType == IMG_SRC_FILE) { + CacheEntry entry; + RetCode ret = CacheManager::GetInstance().Open(GetPath(), *style_, entry); + if (ret != RetCode::OK) { + return; + } + imgInfo = entry.GetImageInfo(); + } else { + imgInfo = *(GetImageInfo()); + } + uint8_t pxSize = DrawUtils::GetPxSizeByColorMode(imgInfo.header.colorMode); + TransformDataInfo imageTranDataInfo = {imgInfo.header, imgInfo.data, pxSize, + static_cast(blurLevel_), + static_cast(algorithm_)}; + + Rect origRect = GetOrigRect(); + transMap_->SetTransMapRect(origRect); + OpacityType opaScale = DrawUtils::GetMixOpacity(opa, style_->imageOpa_); + DrawUtils::GetInstance()->DrawTransform(invalidatedArea, {0, 0}, Color::Black(), opaScale, *transMap_, + imageTranDataInfo); + } + } + } +} + +void UIImageView::SetSrc(const char* src) +{ +#ifndef VERSION_LITE + if (src == nullptr) { + return; + } + const static uint8_t IMG_BYTES_TO_CHECK = 4; // 4: check 4 bytes of image file + char buf[IMG_BYTES_TO_CHECK] = {0}; + int32_t fd = open(src, O_RDONLY); + if (fd < 0) { + return; + } + if (read(fd, buf, IMG_BYTES_TO_CHECK) != IMG_BYTES_TO_CHECK) { + close(fd); + return; + } + close(fd); + bool updated = false; + RemoveAndStopGifAnimator(); + // 0x47 0x49 0x46: GIF file's header + if ((static_cast(buf[0]) == 0x47) && (static_cast(buf[1]) == 0x49) && + (static_cast(buf[2]) == 0x46)) { // 2: array index of GIF file's header + if (gifImageAnimator_ == nullptr) { + gifImageAnimator_ = new GifImageAnimator(this, src); + if (gifImageAnimator_ == nullptr) { + GRAPHIC_LOGE("new GifImageAnimator fail"); + return; + } + } + AddAndStartGifAnimator(); + updated = true; + } else { + updated = image_.SetSrc(src); + } +#else + bool updated = image_.SetSrc(src); +#endif + if (!updated) { + return; + } + needRefresh_ = true; + if (autoEnable_) { + UIImageView::ReMeasure(); + } + Invalidate(); +} + +void UIImageView::ReMeasure() +{ + if (!needRefresh_) { + return; + } + needRefresh_ = false; + + ImageHeader header = {0}; + image_.GetHeader(header); + + imageWidth_ = header.width; + imageHeight_ = header.height; + colorFormat_ = header.colorMode; + + if (autoEnable_) { + Resize(imageWidth_, imageHeight_); + Invalidate(); + } +} + +void UIImageView::SetSrc(const ImageInfo* src) +{ +#ifndef VERSION_LITE + if (!gifFrameFlag_ && (gifImageAnimator_ != nullptr)) { + RemoveAndStopGifAnimator(); + } + gifFrameFlag_ = false; +#endif + bool updated = image_.SetSrc(src); + if (!updated) { + return; + } + needRefresh_ = true; + if (autoEnable_) { + UIImageView::ReMeasure(); + } + Invalidate(); +} + +#ifndef VERSION_LITE +void UIImageView::AddAndStartGifAnimator() +{ + if (gifImageAnimator_ != nullptr) { + AnimatorManager::GetInstance()->Add(gifImageAnimator_); + gifImageAnimator_->Start(); + } +} + +void UIImageView::RemoveAndStopGifAnimator() +{ + if (gifImageAnimator_ != nullptr) { + gifImageAnimator_->Stop(); + AnimatorManager::GetInstance()->Remove(gifImageAnimator_); + delete gifImageAnimator_; + gifImageAnimator_ = nullptr; + } +} +#endif +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/components/ui_label.cpp b/frameworks/components/ui_label.cpp new file mode 100644 index 0000000..f56f053 --- /dev/null +++ b/frameworks/components/ui_label.cpp @@ -0,0 +1,365 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "components/ui_label.h" +#include "font/ui_font.h" +#include "graphic_log.h" +#include "themes/theme_manager.h" + +namespace OHOS { +class LabelAnimator : public Animator, public AnimatorCallback { +public: + LabelAnimator(uint16_t textX, uint16_t labelX, int16_t startPos, UIView* view) + : Animator(this, view, 0, true), + startPos_(startPos), + textX_(textX), + labelX_(labelX), + offsetX_(startPos), + waitCount_(ANIM_WAIT_COUNT), + speed_(0), + preRunTime_(0), + decimal_(0) + { + AnimatorManager::GetInstance()->Add(this); + } + + virtual ~LabelAnimator() + { + AnimatorManager::GetInstance()->Remove(this); + } + + int16_t GetStartPos() const + { + return startPos_; + } + + void SetStartPos(int16_t pos) + { + startPos_ = pos; + } + + void UpdateWidth(uint16_t textWidth, uint16_t labelWidth) + { + textX_ = textWidth; + labelX_ = labelWidth; + waitCount_ = ANIM_WAIT_COUNT; + preRunTime_ = 0; + decimal_ = 0; + offsetX_ = startPos_; + static_cast(view_)->offsetX_ = offsetX_; + view_->Invalidate(); + } + + void Callback(UIView* view) override + { + if (view == nullptr) { + return; + } + + uint32_t curTime = GetRunTime(); + if (waitCount_ > 0) { + waitCount_--; + preRunTime_ = curTime; + return; + } + uint32_t time = (curTime > preRunTime_) ? (curTime - preRunTime_) : (UINT32_MAX - preRunTime_ + curTime); + // 1000: 1000 milliseconds is 1 second + float floatStep = (static_cast(time * speed_) / 1000) + decimal_; + uint16_t integerStep = static_cast(floatStep); + decimal_ = floatStep - integerStep; + preRunTime_ = curTime; + + if (integerStep != 0) { + offsetX_ -= integerStep; + } else { + return; + } + offsetX_ = ((offsetX_ - labelX_) % (textX_ + labelX_)) + labelX_; + static_cast(view)->offsetX_ = offsetX_; + view->Invalidate(); + } + + void SetAnimatorSpeed(uint16_t animSpeed) + { + speed_ = animSpeed; + decimal_ = 0; + } + +private: + static constexpr uint8_t ANIM_WAIT_COUNT = 50; + int16_t startPos_; + uint16_t textX_; + uint16_t labelX_; + int16_t offsetX_; + uint16_t waitCount_; + uint16_t speed_; + uint32_t preRunTime_; + float decimal_; +}; + +UILabel::UILabel() + : labelText_(nullptr), + needRefresh_(false), + useTextColor_(false), + hasAnimator_(false), + lineBreakMode_(LINE_BREAK_ELLIPSIS), + ellipsisIndex_(Text::TEXT_ELLIPSIS_END_INV), + offsetX_(0), + textColor_(Color::White()), + animator_{nullptr} +{ + Theme* theme = ThemeManager::GetInstance().GetCurrent(); + Style& style = (theme != nullptr) ? (theme->GetLabelStyle()) : (StyleDefault::GetLabelStyle()); + UIView::SetStyle(style); + animator_.speed = DEFAULT_ANIMATOR_SPEED; +} + +UILabel::~UILabel() +{ + if (hasAnimator_) { + animator_.animator->Stop(); + delete animator_.animator; + hasAnimator_ = false; + } + if (labelText_ != nullptr) { + delete labelText_; + labelText_ = nullptr; + } +} + +int16_t UILabel::GetWidth() +{ + InitLabelText(); + if (needRefresh_ && labelText_->IsExpandWidth()) { + ReMeasure(); + } + return UIView::GetWidth(); +} + +int16_t UILabel::GetHeight() +{ + InitLabelText(); + if (needRefresh_ && labelText_->IsExpandHeight()) { + ReMeasure(); + } + return UIView::GetHeight(); +} + +void UILabel::SetStyle(uint8_t key, int64_t value) +{ + UIView::SetStyle(key, value); + RefreshLabel(); +} + +void UILabel::SetText(const char* text) +{ + InitLabelText(); + labelText_->SetText(text); + if (labelText_->IsNeedRefresh()) { + RefreshLabel(); + } +} + +void UILabel::SetLineBreakMode(const uint8_t lineBreakMode) +{ + InitLabelText(); + if ((lineBreakMode >= LINE_BREAK_MAX) || (lineBreakMode_ == lineBreakMode)) { + return; + } + lineBreakMode_ = lineBreakMode; + if ((lineBreakMode_ == LINE_BREAK_ADAPT) || (lineBreakMode_ == LINE_BREAK_STRETCH) || + (lineBreakMode_ == LINE_BREAK_MARQUEE)) { + labelText_->SetExpandWidth(true); + } else { + labelText_->SetExpandWidth(false); + } + if ((lineBreakMode_ == LINE_BREAK_ADAPT) || (lineBreakMode_ == LINE_BREAK_WRAP)) { + labelText_->SetExpandHeight(true); + } else { + labelText_->SetExpandHeight(false); + } + RefreshLabel(); +} + +void UILabel::SetAlign(UITextLanguageAlignment horizontalAlign, UITextLanguageAlignment verticalAlign) +{ + InitLabelText(); + labelText_->SetAlign(horizontalAlign, verticalAlign); + if (labelText_->IsNeedRefresh()) { + RefreshLabel(); + } +} + +void UILabel::SetFontId(uint8_t fontId) +{ + InitLabelText(); + labelText_->SetFontId(fontId); + if (labelText_->IsNeedRefresh()) { + RefreshLabel(); + } +} + +void UILabel::SetFont(const char* name, uint8_t size) +{ + InitLabelText(); + labelText_->SetFont(name, size); + if (labelText_->IsNeedRefresh()) { + RefreshLabel(); + } +} + +uint16_t UILabel::GetTextWidth() +{ + InitLabelText(); + if (labelText_->IsNeedRefresh()) { + Style style = GetStyleConst(); + style.textColor_ = GetTextColor(); + labelText_->ReMeasureTextSize(GetContentRect(), style); + } + return labelText_->GetTextSize().x; +} + +uint16_t UILabel::GetTextHeight() +{ + InitLabelText(); + if (labelText_->IsNeedRefresh()) { + Style style = GetStyleConst(); + style.textColor_ = GetTextColor(); + labelText_->ReMeasureTextSize(GetContentRect(), style); + } + return labelText_->GetTextSize().y; +} + +void UILabel::SetWidth(int16_t width) +{ + if (GetWidth() != width) { + UIView::SetWidth(width); + RefreshLabel(); + } +} + +void UILabel::SetHeight(int16_t height) +{ + if (GetHeight() != height) { + UIView::SetHeight(height); + RefreshLabel(); + } +} + +void UILabel::RefreshLabel() +{ + Invalidate(); + ellipsisIndex_ = Text::TEXT_ELLIPSIS_END_INV; + if (!needRefresh_) { + needRefresh_ = true; + } +} + +void UILabel::ReMeasure() +{ + if (!needRefresh_) { + return; + } + needRefresh_ = false; + InitLabelText(); + Style style = GetStyleConst(); + style.textColor_ = GetTextColor(); + labelText_->ReMeasureTextSize(GetContentRect(), style); + Point textSize = labelText_->GetTextSize(); + switch (lineBreakMode_) { + case LINE_BREAK_ADAPT: + Resize(textSize.x, textSize.y); + break; + case LINE_BREAK_STRETCH: + SetWidth(textSize.x); + break; + case LINE_BREAK_WRAP: + SetHeight(textSize.y); + break; + case LINE_BREAK_ELLIPSIS: + ellipsisIndex_ = labelText_->GetEllipsisIndex(GetContentRect(), style); + break; + case LINE_BREAK_MARQUEE: + RemeasureForMarquee(textSize.x); + break; + default: + break; + } +} + +void UILabel::RemeasureForMarquee(int16_t textWidth) +{ + int16_t rectWidth = GetWidth(); + if (textWidth > rectWidth) { + offsetX_ = GetRollStartPos(); + if (labelText_->GetDirect() == TEXT_DIRECT_RTL) { + labelText_->SetAlign(TEXT_ALIGNMENT_RIGHT); + } else { + labelText_->SetAlign(TEXT_ALIGNMENT_LEFT); + } + if (hasAnimator_) { + static_cast(animator_.animator)->UpdateWidth(textWidth, rectWidth); + } else { + LabelAnimator* animator = new LabelAnimator(textWidth, rectWidth, offsetX_, this); + if (animator == nullptr) { + GRAPHIC_LOGE("new LabelAnimator fail"); + return; + } + animator->SetAnimatorSpeed(animator_.speed); + animator_.animator = animator; + hasAnimator_ = true; + } + animator_.animator->Start(); + } else { + offsetX_ = 0; + if (hasAnimator_) { + animator_.animator->Stop(); + } + } +} + +void UILabel::SetRollStartPos(int16_t pos) +{ + if (hasAnimator_) { + static_cast(animator_.animator)->SetStartPos(pos); + } else { + animator_.pos = pos; + } +} + +int16_t UILabel::GetRollStartPos() const +{ + return hasAnimator_ ? static_cast(animator_.animator)->GetStartPos() : animator_.pos; +} + +void UILabel::SetRollSpeed(uint16_t speed) +{ + if (hasAnimator_) { + static_cast(animator_.animator)->SetAnimatorSpeed(speed); + } else { + animator_.speed = speed; + } +} + +void UILabel::OnDraw(const Rect& invalidatedArea) +{ + InitLabelText(); + UIView::OnDraw(invalidatedArea); + Style style = GetStyleConst(); + style.textColor_ = GetTextColor(); + OpacityType opa = GetMixOpaScale(); + labelText_->OnDraw(invalidatedArea, GetOrigRect(), GetContentRect(), offsetX_, style, ellipsisIndex_, opa); +} +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/components/ui_label_button.cpp b/frameworks/components/ui_label_button.cpp new file mode 100755 index 0000000..2839bdc --- /dev/null +++ b/frameworks/components/ui_label_button.cpp @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "components/ui_label_button.h" +#include "common/typed_text.h" +#include "draw/draw_label.h" +#include "font/ui_font.h" + +namespace OHOS { +UILabelButton::UILabelButton() : labelButtonText_(nullptr), offset_({ 0, 0 }) +{ + labelStyle_ = StyleDefault::GetDefaultStyle(); +} + +void UILabelButton::OnDraw(const Rect& invalidatedArea) +{ + UIButton::OnDraw(invalidatedArea); + + Rect textRect = GetContentRect(); + textRect.SetLeft(textRect.GetLeft() + offset_.x); + textRect.SetTop(textRect.GetTop() + offset_.y); + InitLabelButtonText(); + labelButtonText_->ReMeasureTextSize(textRect, labelStyle_); + OpacityType opa = GetMixOpaScale(); + uint16_t ellipsisIndex = labelButtonText_->GetEllipsisIndex(textRect, labelStyle_); + labelButtonText_->OnDraw(invalidatedArea, GetOrigRect(), textRect, 0, labelStyle_, ellipsisIndex, opa); +} + +UILabelButton::~UILabelButton() +{ + if (labelButtonText_ != nullptr) { + delete labelButtonText_; + labelButtonText_ = nullptr; + } +} +} // namespace OHOS diff --git a/frameworks/components/ui_list.cpp b/frameworks/components/ui_list.cpp new file mode 100755 index 0000000..815d435 --- /dev/null +++ b/frameworks/components/ui_list.cpp @@ -0,0 +1,763 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "components/ui_list.h" + +namespace OHOS { +UIList::Recycle::~Recycle() +{ + ListNode* node = scrapView_.Begin(); + while (node != scrapView_.End()) { + if (node->data_) { + UIView* deleteView = node->data_; + if (deleteView != nullptr) { + delete deleteView; + deleteView = nullptr; + node->data_ = nullptr; + } + } + node = node->next_; + } + scrapView_.Clear(); +} + +void UIList::Recycle::InitRecycle() +{ + if ((adapter_ == nullptr) || (listView_ == nullptr)) { + return; + } + FillActiveView(); + listView_->Invalidate(); +} + +UIView* UIList::Recycle::GetView(int16_t index) +{ + if (adapter_ == nullptr) { + return nullptr; + } + UIView* inView = nullptr; + UIView* retView = nullptr; + + if (scrapView_.Size() != 0) { + inView = scrapView_.Back(); + } + + retView = adapter_->GetView(inView, index); + if (retView != nullptr) { + retView->SetViewIndex(index); + scrapView_.PopBack(); + } + return retView; +} + +void UIList::Recycle::FillActiveView() +{ + if ((adapter_ == nullptr) || (listView_ == nullptr)) { + return; + } + uint16_t index = listView_->GetStartIndex(); + if (listView_->GetDirection() == UIList::VERTICAL) { + int16_t childBottom = 0; + while ((index < adapter_->GetCount()) && (childBottom < listView_->GetHeight())) { + UIView* view = GetView(index); + if (view == nullptr) { + break; + } + listView_->PushBack(view); + if (listView_->childrenTail_) { + childBottom = + listView_->childrenTail_->GetY() + listView_->childrenTail_->GetRelativeRect().GetHeight(); + } else { + break; + } + index++; + } + } else { + int16_t childRight = 0; + while ((index < adapter_->GetCount()) && (childRight < listView_->GetWidth())) { + UIView* view = GetView(index); + listView_->PushBack(view); + if (listView_->childrenTail_) { + childRight = listView_->childrenTail_->GetX() + listView_->childrenTail_->GetRelativeRect().GetWidth(); + } else { + break; + } + index++; + } + } +} + +UIList::UIList() + : onSelectedView_(nullptr), + isLoopList_(false), + isReCalculateDragEnd_(true), + autoAlign_(false), + startIndex_(0), + topIndex_(0), + bottomIndex_(0), + selectPosition_(0), + onSelectedIndex_(0), + recycle_(this), + scrollListener_(nullptr) +{ +#if ENABLE_ROTATE_INPUT + rotateFactor_ = 1; + rotateThreshold_ = 4; // 4: which means 25% of half view size +#endif +#if ENABLE_MOTOR + motorType_ = MotorType::MOTOR_TYPE_ONE; +#endif + direction_ = VERTICAL; + touchable_ = true; + draggable_ = true; + dragParentInstead_ = false; +} + +UIList::UIList(uint8_t direction) + : onSelectedView_(nullptr), + isLoopList_(false), + isReCalculateDragEnd_(true), + autoAlign_(false), + startIndex_(0), + topIndex_(0), + bottomIndex_(0), + selectPosition_(0), + onSelectedIndex_(0), + recycle_(this), + scrollListener_(nullptr) +{ +#if ENABLE_ROTATE_INPUT + rotateFactor_ = 1; + rotateThreshold_ = 4; // 4: which means 25% of half view size +#endif +#if ENABLE_MOTOR + motorType_ = MotorType::MOTOR_TYPE_ONE; +#endif + direction_ = direction; + touchable_ = true; + draggable_ = true; + dragParentInstead_ = false; +} + +UIList::~UIList() +{ + UIView* view = GetChildrenHead(); + while (view != nullptr) { + UIView* tmp = view->GetNextSibling(); + delete view; + view = tmp; + } +} + +bool UIList::OnDragEvent(const DragEvent& event) +{ + if (scrollAnimator_.GetState() != Animator::STOP) { + UIAbstractScroll::StopAnimator(); + } + int16_t xDistance = event.GetDeltaX(); + int16_t yDistance = event.GetDeltaY(); + isReCalculateDragEnd_ = true; + if (direction_ == VERTICAL) { + RefreshDeltaY(yDistance); + DragYInner(yDistance); + } else { + DragXInner(xDistance); + } + return UIView::OnDragEvent(event); +} + +bool UIList::OnDragEndEvent(const DragEvent& event) +{ + Point last = event.GetPreLastPoint(); + Point current = event.GetLastPoint(); + if ((last.x == current.x) && (last.y == current.y)) { + last = current; + current = event.GetCurrentPos(); + } + isReCalculateDragEnd_ = false; + if (!DragThrowAnimator(current, last)) { + if (scrollListener_ && (scrollListener_->GetScrollState() == ListScrollListener::SCROLL_STATE_MOVE)) { + scrollListener_->SetScrollState(ListScrollListener::SCROLL_STATE_STOP); + scrollListener_->OnScrollEnd(onSelectedIndex_, onSelectedView_); + } + } + return UIView::OnDragEndEvent(event); +} + +bool UIList::OnPressEvent(const PressEvent& event) +{ + StopAnimator(); + return UIView::OnPressEvent(event); +} + +#if ENABLE_ROTATE_INPUT +bool UIList::OnRotateEvent(const RotateEvent& event) +{ + int16_t tmpRotateLen = static_cast(event.GetRotate() * rotateFactor_); + int16_t midPointX = static_cast(GetWidth() / 2); // 2 : Get the middle point X coord of the view + int16_t midPointY = static_cast(GetHeight() / 2); // 2 : Get the middle point Y coord of the view + Point last, current; +#if ENABLE_MOTOR + MotorFunc motorFunc = FocusManager::GetInstance()->GetMotorFunc(); +#endif + + if (!throwDrag_ || ((MATH_ABS(tmpRotateLen) < (midPointX / rotateThreshold_)) && + (MATH_ABS(tmpRotateLen) < (midPointY / rotateThreshold_)))) { + ScrollBy(tmpRotateLen); + if (event.GetRotate() == 0) { + isReCalculateDragEnd_ = false; + DragThrowAnimator(Point{0, 0}, Point{0, 0}); + } + } else { + tmpRotateLen += tmpRotateLen; + last = Point{midPointX, midPointY}; + if (direction_ == VERTICAL) { + current = Point{midPointX, static_cast(midPointY + tmpRotateLen)}; + } else { + current = Point{static_cast(midPointX + tmpRotateLen), midPointY}; + } + isReCalculateDragEnd_ = false; + DragThrowAnimator(current, last); +#if ENABLE_MOTOR + if (motorFunc != nullptr && motorType_ == MotorType::MOTOR_TYPE_TWO) { + motorFunc(MotorType::MOTOR_TYPE_TWO); + } +#endif + } + +#if ENABLE_MOTOR + if (motorFunc != nullptr && motorType_ == MotorType::MOTOR_TYPE_ONE) { + motorFunc(MotorType::MOTOR_TYPE_ONE); + } +#endif + + return UIView::OnRotateEvent(event); +} +#endif + +void UIList::ScrollBy(int16_t distance) +{ + if (direction_ == VERTICAL) { + DragYInner(distance); + } else { + DragXInner(distance); + } + if (scrollListener_ && (scrollListener_->GetScrollState() == ListScrollListener::SCROLL_STATE_MOVE)) { + scrollListener_->SetScrollState(ListScrollListener::SCROLL_STATE_STOP); + scrollListener_->OnScrollEnd(onSelectedIndex_, onSelectedView_); + } +} + +bool UIList::DragXInner(int16_t distance) +{ + if (IsNeedReCalculateDragEnd()) { + return false; + } + int16_t listWidth = GetWidth(); + if (distance == 0) { + return true; + } + int16_t reboundSize = reboundSize_; + if (isLoopList_ || (scrollAnimator_.GetState() != Animator::STOP)) { + reboundSize = 0; + } + bool ret = 0; + do { + ret = MoveChildStep(distance); + } while (ret); + + if (isLoopList_) { + return MoveOffset(distance); + } + if (distance > 0) { + if (childrenHead_ && (childrenHead_->GetX() + distance > scrollBlankSize_ + reboundSize)) { + distance = scrollBlankSize_ + reboundSize - childrenHead_->GetX(); + } + } else { + if (childrenTail_) { + if (childrenTail_->GetRelativeRect().GetRight() <= listWidth - scrollBlankSize_ - reboundSize) { + distance = 0; + } else if (listWidth - (childrenTail_->GetX() + childrenTail_->GetRelativeRect().GetWidth() + distance) > + scrollBlankSize_ + reboundSize) { + distance = listWidth - scrollBlankSize_ - reboundSize - childrenTail_->GetX() - + childrenTail_->GetRelativeRect().GetWidth(); + } + } + } + return MoveOffset(distance); +} + +bool UIList::DragYInner(int16_t distance) +{ + if (IsNeedReCalculateDragEnd()) { + return false; + } + int16_t listHeigh = GetHeight(); + if (distance == 0) { + return true; + } + int16_t reboundSize = reboundSize_; + if (isLoopList_ || (scrollAnimator_.GetState() != Animator::STOP)) { + reboundSize = 0; + } + bool ret = 0; + do { + ret = MoveChildStep(distance); + } while (ret); + + if (isLoopList_) { + return MoveOffset(distance); + } + if (distance > 0) { + if (childrenHead_ && (childrenHead_->GetY() + distance > scrollBlankSize_ + reboundSize)) { + distance = scrollBlankSize_ + reboundSize - childrenHead_->GetY(); + } + } else { + if (childrenTail_) { + if (childrenTail_->GetRelativeRect().GetBottom() <= listHeigh - scrollBlankSize_ - reboundSize) { + distance = 0; + } else if (listHeigh - (childrenTail_->GetY() + childrenTail_->GetRelativeRect().GetHeight() + distance) > + scrollBlankSize_ + reboundSize) { + distance = listHeigh - scrollBlankSize_ - reboundSize - childrenTail_->GetY() - + childrenTail_->GetRelativeRect().GetHeight(); + } + } + } + return MoveOffset(distance); +} + +bool UIList::MoveOffset(int16_t offset) +{ + if (offset == 0) { + return false; + } + if (direction_ == VERTICAL) { + MoveChildByOffset(0, offset); + } else { + MoveChildByOffset(offset, 0); + } + Invalidate(); + if (scrollListener_ && (scrollListener_->GetScrollState() == ListScrollListener::SCROLL_STATE_STOP)) { + scrollListener_->SetScrollState(ListScrollListener::SCROLL_STATE_MOVE); + scrollListener_->OnScrollStart(onSelectedIndex_, onSelectedView_); + } + + return true; +} + +bool UIList::IsNeedReCalculateDragEnd() +{ + if (!autoAlign_ || isReCalculateDragEnd_ || (onSelectedView_ == nullptr)) { + return false; + } + int16_t animationLess = 0; + if (direction_ == VERTICAL) { + animationLess = animatorCallback_.endValueY_ - animatorCallback_.previousValueY_; + } else { + animationLess = animatorCallback_.endValueX_ - animatorCallback_.previousValueX_; + } + if (!isDragging_ || (MATH_ABS(animationLess) > RECALCULATE_DRAG_DISTANCE)) { + return false; + } + return true; +} +bool UIList::ReCalculateDragEnd() +{ + if ((onSelectedView_ == nullptr) || isReCalculateDragEnd_ || !autoAlign_) { + return false; + } + + int16_t offsetX = 0; + int16_t offsetY = 0; + if (direction_ == VERTICAL) { + // 2: half + offsetY = selectPosition_ - (onSelectedView_->GetY() + (onSelectedView_->GetRelativeRect().GetHeight() / 2)); + } else { + // 2: half + offsetX = selectPosition_ - (onSelectedView_->GetX() + (onSelectedView_->GetRelativeRect().GetWidth() / 2)); + } + animatorCallback_.SetDragStartValue(0, 0); + animatorCallback_.SetDragEndValue(offsetX, offsetY); + animatorCallback_.SetDragTimes(RECALCULATE_DRAG_TIMES * DRAG_ACC_FACTOR / GetDragACCLevel()); + scrollAnimator_.Start(); + isReCalculateDragEnd_ = true; + return true; +} + +bool UIList::MoveChildStepInner(int16_t distance, + int16_t (UIView::*pfnGetXOrY)() const, + int16_t (Rect::*pfnGetWidthOrHeight)() const) +{ + bool popRet = false; + bool pushRet = false; + if (distance > 0) { + if ((childrenHead_ == nullptr) || ((childrenHead_->*pfnGetXOrY)() + distance > 0)) { + uint16_t index = GetIndexDec(topIndex_); + if (index == topIndex_) { + return false; + } + UIView* newView = recycle_.GetView(index); + if (newView == nullptr) { + return false; + } + PushFront(newView); + pushRet = true; + } + if (childrenTail_ != nullptr && + ((childrenTail_->*pfnGetXOrY)() + distance > (this->GetRelativeRect().*pfnGetWidthOrHeight)())) { + PopItem(childrenTail_); + popRet = true; + } + } else { + if ((childrenTail_ == nullptr) || + ((childrenTail_->*pfnGetXOrY)() + (childrenTail_->GetRelativeRect().*pfnGetWidthOrHeight)() + distance < + (this->GetRelativeRect().*pfnGetWidthOrHeight)())) { + UIView* newView = recycle_.GetView(GetIndexInc(bottomIndex_)); + if (newView == nullptr) { + return false; + } + PushBack(newView); + pushRet = true; + } + if (childrenHead_ && + (childrenHead_->*pfnGetXOrY)() + distance + (childrenHead_->GetRelativeRect().*pfnGetWidthOrHeight)() < 0) { + PopItem(childrenHead_); + popRet = true; + } + } + return (popRet || pushRet); +} + +bool UIList::MoveChildStep(int16_t distance) +{ + if (direction_ == VERTICAL) { + return MoveChildStepInner(distance, &UIView::GetY, &Rect::GetHeight); + } else { + return MoveChildStepInner(distance, &UIView::GetX, &Rect::GetWidth); + } +} + +void UIList::SetAdapter(AbstractAdapter* adapter) +{ + recycle_.SetAdapter(adapter); + recycle_.InitRecycle(); +} + +UIView* UIList::GetSelectView() +{ + if (onSelectedView_ != nullptr) { + return onSelectedView_; + } + if ((childrenHead_ == nullptr) || (selectPosition_ == 0)) { + return nullptr; + } + UIView* child = childrenHead_; + while (child != nullptr) { + if (direction_ == VERTICAL) { + if ((child->GetY() <= selectPosition_) && + (child->GetY() + child->GetRelativeRect().GetHeight() >= selectPosition_)) { + if (scrollListener_ != nullptr) { + scrollListener_->OnItemSelected(child->GetViewIndex(), child); + } + return child; + } + } else { + if ((child->GetX() <= selectPosition_) && + (child->GetX() + child->GetRelativeRect().GetWidth() >= selectPosition_)) { + if (scrollListener_ != nullptr) { + scrollListener_->OnItemSelected(child->GetViewIndex(), child); + } + return child; + } + } + child = child->GetNextSibling(); + } + return nullptr; +} + +void UIList::PushBack(UIView* view) +{ + if (view == nullptr) { + return; + } + if (childrenTail_ == nullptr) { + SetHead(view); + } else { + if (direction_ == VERTICAL) { + view->SetPosition(0, childrenTail_->GetY() + childrenTail_->GetRelativeRect().GetHeight()); + } else { + view->SetPosition(childrenTail_->GetX() + childrenTail_->GetRelativeRect().GetWidth(), 0); + } + bottomIndex_ = GetIndexInc(bottomIndex_); + } + + view->SetDragParentInstead(true); + UIViewGroup::Add(view); +} + +void UIList::PushFront(UIView* view) +{ + if (view == nullptr) { + return; + } + if (GetChildrenHead() == nullptr) { + SetHead(view); + } else { + if (direction_ == VERTICAL) { + view->SetPosition(0, GetChildrenHead()->GetY() - view->GetRelativeRect().GetHeight()); + } else { + view->SetPosition(GetChildrenHead()->GetX() - view->GetRelativeRect().GetWidth(), 0); + } + topIndex_ = GetIndexDec(topIndex_); + } + view->SetDragParentInstead(true); + UIViewGroup::Insert(nullptr, view); +} + +void UIList::PopItem(UIView* view) +{ + if (view == nullptr) { + return; + } + recycle_.AddScrapView(view); + if (view == GetChildrenHead()) { + topIndex_ = GetIndexInc(topIndex_); + } + + if (view == childrenTail_) { + bottomIndex_ = GetIndexDec(bottomIndex_); + } + UIViewGroup::Remove(view); +} + +void UIList::SetHead(UIView* view) +{ + if (view != nullptr) { + view->SetPosition(0, 0); + topIndex_ = startIndex_; + bottomIndex_ = startIndex_; + } +} + +void UIList::MoveChildByOffset(int16_t xOffset, int16_t yOffset) +{ + UIView* view = GetChildrenHead(); + if (view == nullptr) { + return; + } + int16_t x; + int16_t y; + int16_t height; + int16_t width; + + if ((onSelectedIndex_ != NULL_SELECT_INDEX) && (selectPosition_ != 0)) { + if (direction_ == VERTICAL) { + height = view->GetRelativeRect().GetHeight(); + if ((GetChildrenHead()->GetY() + yOffset > selectPosition_) || + (childrenTail_->GetY() + height + yOffset < selectPosition_)) { + onSelectedIndex_ = NULL_SELECT_INDEX; + onSelectedView_ = nullptr; + if (scrollListener_ != nullptr) { + scrollListener_->OnItemSelected(onSelectedIndex_, onSelectedView_); + } + } + } else { + width = view->GetRelativeRect().GetWidth(); + if ((GetChildrenHead()->GetX() + xOffset > selectPosition_) || + (childrenTail_->GetX() + width < selectPosition_)) { + onSelectedIndex_ = NULL_SELECT_INDEX; + onSelectedView_ = nullptr; + if (scrollListener_ != nullptr) { + scrollListener_->OnItemSelected(onSelectedIndex_, onSelectedView_); + } + } + } + } + bool isSelectViewFind = false; + while (view != nullptr) { + x = view->GetX() + xOffset; + y = view->GetY() + yOffset; + view->SetPosition(x, y); + if ((selectPosition_ != 0) && !isSelectViewFind) { + if (direction_ == VERTICAL) { + height = view->GetRelativeRect().GetHeight(); + /* Views may be the same but have different indexes because of view recycling. */ + if ((y <= selectPosition_) && (y + height >= selectPosition_) && + ((onSelectedView_ != view) || (onSelectedIndex_ != view->GetViewIndex()))) { + onSelectedIndex_ = view->GetViewIndex(); + onSelectedView_ = view; + if (scrollListener_ != nullptr) { + scrollListener_->OnItemSelected(onSelectedIndex_, onSelectedView_); + } + isSelectViewFind = true; + } + } else { + width = view->GetRelativeRect().GetWidth(); + if ((x <= selectPosition_) && (x + width >= selectPosition_) && + ((onSelectedView_ != view) || (onSelectedIndex_ != view->GetViewIndex()))) { + onSelectedIndex_ = view->GetViewIndex(); + onSelectedView_ = view; + if (scrollListener_ != nullptr) { + scrollListener_->OnItemSelected(onSelectedIndex_, onSelectedView_); + } + isSelectViewFind = true; + } + } + } + view = view->GetNextSibling(); + } +} + +void UIList::StopAnimator() +{ + UIAbstractScroll::StopAnimator(); + if (!ReCalculateDragEnd()) { + if ((scrollListener_ != nullptr) && + (scrollListener_->GetScrollState() == ListScrollListener::SCROLL_STATE_MOVE)) { + scrollListener_->SetScrollState(ListScrollListener::SCROLL_STATE_STOP); + scrollListener_->OnScrollEnd(onSelectedIndex_, onSelectedView_); + } + } +} + +uint16_t UIList::GetIndexInc(uint16_t index) +{ + uint16_t ret = index + 1; + if (isLoopList_ && (recycle_.GetAdapterItemCount() != 0)) { + ret = ret % recycle_.GetAdapterItemCount(); + } + return ret; +} + +uint16_t UIList::GetIndexDec(uint16_t index) +{ + if (index == 0) { + if (isLoopList_) { + return recycle_.GetAdapterItemCount() - 1; + } else { + return 0; + } + } else { + return index - 1; + } +} + +void UIList::ScrollTo(uint16_t index) +{ + UIView* child = GetChildrenHead(); + UIView* tmp = nullptr; + while (child != nullptr) { + tmp = child; + child = child->GetNextSibling(); + PopItem(tmp); + } + onSelectedView_ = nullptr; + SetStartIndex(index); + recycle_.InitRecycle(); +} + +void UIList::RefreshList() +{ + int16_t topIndex = topIndex_; + UIView* child = GetChildrenHead(); + UIView* tmp = nullptr; + int16_t offset = 0; + if (child != nullptr) { + if (direction_ == VERTICAL) { + offset = child->GetY(); + } else { + offset = child->GetX(); + } + } + + while (child != nullptr) { + tmp = child; + child = child->GetNextSibling(); + PopItem(tmp); + } + onSelectedView_ = nullptr; + + uint16_t tmpStartIndex = startIndex_; + if (topIndex > recycle_.GetAdapterItemCount() - 1) { + startIndex_ = 0; + offset = 0; + } else { + startIndex_ = topIndex; + } + recycle_.InitRecycle(); + startIndex_ = tmpStartIndex; + + if (direction_ == VERTICAL) { + DragYInner(offset); + } else { + DragXInner(offset); + } + Invalidate(); +} + +void UIList::RemoveAll() +{ + UIViewGroup::RemoveAll(); + recycle_.ClearScrapView(); +} + +void UIList::CalculateReboundDistance(int16_t& dragDistanceX, int16_t& dragDistanceY) +{ + if (isLoopList_) { + return; + } + Rect rect = GetAllChildRelativeRect(); + int16_t top = rect.GetTop(); + int16_t bottom = rect.GetBottom(); + int16_t scrollHeight = GetHeight(); + int16_t left = rect.GetLeft(); + int16_t right = rect.GetRight(); + int16_t scrollWidth = GetWidth(); + if ((direction_ == VERTICAL) || (direction_ == HORIZONTAL_AND_VERTICAL)) { + if (top > scrollBlankSize_) { + if ((dragDistanceY + top) > (scrollBlankSize_ + reboundSize_)) { + dragDistanceY = 0; + } + dragDistanceY += scrollBlankSize_ - (top + dragDistanceY); + } + if (bottom < (scrollHeight - scrollBlankSize_ - 1)) { + if ((dragDistanceY + bottom) < (scrollHeight - scrollBlankSize_ - reboundSize_ - 1)) { + dragDistanceY = 0; + } + dragDistanceY += scrollHeight - scrollBlankSize_ - 1 - (bottom + dragDistanceY); + } + } else { + if (left > scrollBlankSize_) { + if ((dragDistanceX + left) > (scrollBlankSize_ + reboundSize_)) { + dragDistanceX = 0; + } + dragDistanceX += scrollBlankSize_ - (left + dragDistanceX); + } + if (right < (scrollWidth - scrollBlankSize_ - 1)) { + if ((dragDistanceX + right) < (scrollWidth - scrollBlankSize_ - reboundSize_ - 1)) { + dragDistanceX = 0; + } + dragDistanceX += scrollWidth - scrollBlankSize_ - 1 - (right + dragDistanceX); + } + } +} + +#if ENABLE_MOTOR +void UIList::SetMotorType(MotorType motorType) +{ + motorType_ = motorType; +} +#endif +} // namespace OHOS diff --git a/frameworks/components/ui_picker.cpp b/frameworks/components/ui_picker.cpp new file mode 100755 index 0000000..5380931 --- /dev/null +++ b/frameworks/components/ui_picker.cpp @@ -0,0 +1,462 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "components/ui_picker.h" +#include "draw/draw_line.h" +#include "draw/draw_rect.h" +#include "themes/theme_manager.h" + +namespace OHOS { +class PickerListScrollListener : public ListScrollListener { +public: + PickerListScrollListener(UIPicker* picker, UIList* list) + : listView_(list), pickerView_(picker), selectView_(nullptr), lastSelectView_(nullptr), + selectIndex_(0), isInitted_(false){} + + virtual ~PickerListScrollListener() {} + + void OnItemSelected(int16_t index, UIView* view) override + { + if (!isInitted_) { + return; + } + + if ((lastSelectView_ != nullptr) && (listView_ != nullptr) && (pickerView_ != nullptr) && (view != nullptr)) { + lastSelectView_->SetStyle(STYLE_TEXT_COLOR, pickerView_->GetBackgroundTextColor().full); + if (pickerView_->backgroundFontName_ == nullptr) { + static_cast(lastSelectView_)->SetFontId(pickerView_->backgroundFontId_); + } else { + static_cast(lastSelectView_) + ->SetFont(pickerView_->backgroundFontName_, pickerView_->backgroundFontSize_); + } + view->SetStyle(STYLE_TEXT_COLOR, pickerView_->GetHighlightTextColor().full); + if (pickerView_->highlightFontName_ == nullptr) { + static_cast(view)->SetFontId(pickerView_->highlightFontId_); + } else { + static_cast(view) + ->SetFont(pickerView_->highlightFontName_, pickerView_->highlightFontSize_); + } + lastSelectView_ = view; + selectIndex_ = index; + listView_->Invalidate(); + } + } + + void OnScrollEnd(int16_t index, UIView* view) override + { + if ((view == nullptr) || (listView_ == nullptr) || (pickerView_ == nullptr)) { + return; + } + + if (lastSelectView_ != nullptr) { + lastSelectView_->SetStyle(STYLE_TEXT_COLOR, pickerView_->GetBackgroundTextColor().full); + if (pickerView_->backgroundFontName_ == nullptr) { + static_cast(lastSelectView_)->SetFontId(pickerView_->backgroundFontId_); + } else { + static_cast(lastSelectView_) + ->SetFont(pickerView_->backgroundFontName_, pickerView_->backgroundFontSize_); + } + lastSelectView_ = view; + } + + view->SetStyle(STYLE_TEXT_COLOR, pickerView_->GetHighlightTextColor().full); + if (pickerView_->highlightFontName_ == nullptr) { + static_cast(view)->SetFontId(pickerView_->highlightFontId_); + } else { + static_cast(view) + ->SetFont(pickerView_->highlightFontName_, pickerView_->highlightFontSize_); + } + + listView_->Invalidate(); + selectView_ = view; + selectIndex_ = index; + + if (pickerView_->pickerListener_) { + pickerView_->pickerListener_->OnPickerStoped(*pickerView_); + } + } + + void SetSelectView(UIView* view) + { + selectView_ = view; + lastSelectView_ = view; + } + + const UIView* GetSelectView() const + { + return selectView_; + } + + void SetSelectIndex(uint16_t index) + { + selectIndex_ = index; + } + + uint16_t GetSelectIndex() const + { + return selectIndex_; + } + + void SetInitStatus(bool status) + { + isInitted_ = status; + } + +private: + UIList* listView_; + UIPicker* pickerView_; + UIView* selectView_; + UIView* lastSelectView_; + uint16_t selectIndex_; + bool isInitted_; +}; + +UIPicker::UIPicker() + : isWidthSet_(false), + isHeightSet_(false), + textAdapter_(nullptr), + maxCount_(0), + setSelectedIndex_(0), + backgroundFontSize_(0), + highlightFontSize_(0), + backgroundFontName_(nullptr), + highlightFontName_(nullptr), + itemsWidth_(0), + itemsHeight_(0), + rangeValue_(nullptr), + rangeValueCount_(0), + startValue_(0), + endValue_(0), + isSetAdaptered_(false), + pickerListener_(nullptr) +{ + Theme* theme = ThemeManager::GetInstance().GetCurrent(); + if (theme != nullptr) { + style_ = &(theme->GetPickerBackgroundStyle()); + } else { + style_ = &(StyleDefault::GetPickerBackgroundStyle()); + } + backgroundFontId_ = style_->font_; + backgroundColor_ = style_->textColor_; + direct_ = UITextLanguageDirect::TEXT_DIRECT_LTR; + + if (theme != nullptr) { + style_ = &(theme->GetPickerHighlightStyle()); + } else { + style_ = &(StyleDefault::GetPickerHighlightStyle()); + } + highlightFontId_ = style_->font_; + highlightColor_ = style_->textColor_; + + list_.SetThrowDrag(true); +#if ENABLE_ROTATE_INPUT + list_.rotateFactor_ = 5; // 5: need to fit device to change + list_.rotateThreshold_ = 20; // 20: which means 20% of half view size +#endif +#if ENABLE_MOTOR + list_.SetMotorType(MotorType::MOTOR_TYPE_TWO); +#endif + list_.SetLoopState(false); + list_.EnableAutoAlign(true); + list_.SetIntercept(false); + PickerListScrollListener* listener = new PickerListScrollListener(this, &list_); + list_.SetScrollStateListener(listener); + listListener_ = static_cast(listener); + Add(&list_); +} + +UIPicker::~UIPicker() +{ + ClearValues(); + Remove(&list_); + if (listListener_ != nullptr) { + delete static_cast(listListener_); + listListener_ = nullptr; + } + + if (backgroundFontName_ != nullptr) { + UIFree(backgroundFontName_); + backgroundFontName_ = nullptr; + } + + if (highlightFontName_ != nullptr) { + UIFree(highlightFontName_); + highlightFontName_ = nullptr; + } + + if (textAdapter_ != nullptr) { + delete textAdapter_; + textAdapter_ = nullptr; + } +} + +bool UIPicker::SetValues(int16_t start, int16_t end) +{ + if (start > end) { + return false; + } + + startValue_ = start; + endValue_ = end; + return RefreshValues(start, end); +} + +bool UIPicker::SetValues(const char* value[], uint16_t count) +{ + if (value == nullptr) { + return false; + } + + rangeValue_ = value; + rangeValueCount_ = count; + return RefreshValues(value, count); +} + +void UIPicker::Refresh() +{ + if (rangeValue_) { + RefreshValues(rangeValue_, rangeValueCount_); + } else if ((startValue_ != 0) || (endValue_ != 0)) { + RefreshValues(startValue_, endValue_); + } +} + +bool UIPicker::RefreshValues(int16_t start, int16_t end) +{ + if (!isWidthSet_ || !isHeightSet_ || !itemsHeight_ || ((start == 0) && (end == 0))) { + return false; + } + + ClearList(); + InitTextAdapter(); + textAdapter_->SetData(start, end); + maxCount_ = end - start + 1; + RefreshList(); + if (setSelectedIndex_) { + RefreshSelected(setSelectedIndex_); + } + return true; +} + +bool UIPicker::RefreshValues(const char* value[], uint16_t count) +{ + if (value == nullptr || !isWidthSet_ || !isHeightSet_ || !itemsHeight_) { + return false; + } + + ClearList(); + for (uint16_t i = 0; i < count; i++) { + dataList_.PushBack(value[i]); + } + InitTextAdapter(); + textAdapter_->SetData(&dataList_); + maxCount_ = count; + RefreshList(); + if (setSelectedIndex_) { + RefreshSelected(setSelectedIndex_); + } + + return true; +} + +void UIPicker::RefreshList() +{ + int16_t height = GetHeight(); + itemsWidth_ = GetWidth(); + textAdapter_->SetWidth(itemsWidth_); + textAdapter_->SetHeight(itemsHeight_); + textAdapter_->SetLineBreakMode(UILabel::LINE_BREAK_CLIP); + if (backgroundFontName_ == nullptr) { + textAdapter_->SetFontId(backgroundFontId_); + } else { + textAdapter_->SetFont(backgroundFontName_, backgroundFontSize_); + } + textAdapter_->GetStyle().textColor_ = backgroundColor_; + textAdapter_->SetDirect(direct_); + list_.SetHeight(height); + list_.SetWidth(itemsWidth_); + list_.SetPosition(GetWidth() / 2 - list_.GetWidth() / 2, 0); // 2: half + list_.SetScrollBlankSize((height - itemsHeight_) / 2); // 2: half + list_.SetSelectPosition(height / 2); // 2: half + list_.SetStyle(*style_); + list_.SetStyle(STYLE_BORDER_WIDTH, 0); + list_.SetStyle(STYLE_BACKGROUND_OPA, 0); + if (!isSetAdaptered_) { + list_.SetAdapter(textAdapter_); + isSetAdaptered_ = true; + } + + list_.RefreshList(); + RefreshSelected(0); +} + +void UIPicker::ClearValues() +{ + rangeValue_ = nullptr; + rangeValueCount_ = 0; + setSelectedIndex_ = 0; + ClearList(); +} + +void UIPicker::ClearList() +{ + maxCount_ = 0; + itemsWidth_ = 0; + if (listListener_) { + PickerListScrollListener* listListener = static_cast(listListener_); + listListener->SetSelectView(nullptr); + listListener->SetSelectIndex(0); + listListener->SetInitStatus(false); + } + dataList_.Clear(); +} + +bool UIPicker::SetSelected(uint16_t index) +{ + setSelectedIndex_ = index; + return RefreshSelected(index); +} + +bool UIPicker::RefreshSelected(uint16_t index) +{ + if (itemsHeight_ && (maxCount_ > index) && (list_.GetChildrenHead() != nullptr) && isWidthSet_ && isHeightSet_) { + PickerListScrollListener* listListener = static_cast(listListener_); + listListener->SetInitStatus(false); + // 2: half + int16_t yOffset = (list_.GetHeight() - itemsHeight_) / 2 - + itemsHeight_ * (index - list_.GetChildrenHead()->GetViewIndex()); + list_.SetScrollStateListener(nullptr); + list_.ScrollBy(yOffset - list_.GetChildrenHead()->GetY()); + list_.SetScrollStateListener(listListener); + listListener->SetScrollState(ListScrollListener::SCROLL_STATE_STOP); + UIView* childView = static_cast(list_.GetChildrenHead()); + uint16_t lastSelectIndex = listListener->GetSelectIndex(); + + int16_t viewIndex; + while (childView != nullptr) { + viewIndex = childView->GetViewIndex(); + if (viewIndex == lastSelectIndex) { + childView->SetStyle(STYLE_TEXT_COLOR, GetBackgroundTextColor().full); + if (backgroundFontName_ == nullptr) { + static_cast(childView)->SetFontId(backgroundFontId_); + } else { + static_cast(childView)->SetFont(backgroundFontName_, backgroundFontSize_); + } + } + if (viewIndex == index) { + childView->SetStyle(STYLE_TEXT_COLOR, GetHighlightTextColor().full); + if (highlightFontName_ == nullptr) { + static_cast(childView)->SetFontId(highlightFontId_); + } else { + static_cast(childView)->SetFont(highlightFontName_, highlightFontSize_); + } + listListener->SetSelectView(childView); + listListener->SetSelectIndex(index); + listListener->SetInitStatus(true); + } + childView = childView->GetNextSibling(); + } + list_.Invalidate(); + return true; + } + return false; +} + +uint16_t UIPicker::GetSelected() const +{ + PickerListScrollListener* listListener = static_cast(listListener_); + return listListener->GetSelectIndex(); +} + +void UIPicker::SetFontId(uint8_t backgroundFontId, uint8_t highlightFontId) +{ + backgroundFontId_ = backgroundFontId; + if (backgroundFontName_ != nullptr) { + UIFree(backgroundFontName_); + backgroundFontName_ = nullptr; + } + + highlightFontId_ = highlightFontId; + if (highlightFontName_ != nullptr) { + UIFree(highlightFontName_); + highlightFontName_ = nullptr; + } + + Refresh(); +} + +void UIPicker::SetBackgroundFont(const char* name, uint8_t size) +{ + Text::SetFont(name, size, backgroundFontName_, backgroundFontSize_); + Refresh(); +} + +void UIPicker::SetHighlightFont(const char* name, uint8_t size) +{ + Text::SetFont(name, size, highlightFontName_, highlightFontSize_); + Refresh(); +} + +void UIPicker::SetTextColor(ColorType backgroundColor, ColorType highlightColor) +{ + backgroundColor_ = backgroundColor; + highlightColor_ = highlightColor; + Refresh(); +} + +void UIPicker::SetItemHeight(int16_t height) +{ + if (height > 0) { + itemsHeight_ = height; + Refresh(); + } +} + +void UIPicker::SetWidth(int16_t width) +{ + if (width > 0) { + UIView::SetWidth(width); + isWidthSet_ = true; + Refresh(); + } +} + +void UIPicker::SetHeight(int16_t height) +{ + if (height > 0) { + UIView::SetHeight(height); + isHeightSet_ = true; + Refresh(); + } +} + +void UIPicker::SetLoopState(bool state) +{ + list_.SetLoopState(state); +} + +void UIPicker::SetDirect(UITextLanguageDirect direct) +{ + direct_ = direct; + Refresh(); +} + +void UIPicker::SetTextFormatter(TextFormatter* formatter) +{ + InitTextAdapter(); + textAdapter_->SetTextFormatter(formatter); + Refresh(); +} +} diff --git a/frameworks/components/ui_qrcode.cpp b/frameworks/components/ui_qrcode.cpp new file mode 100755 index 0000000..7011816 --- /dev/null +++ b/frameworks/components/ui_qrcode.cpp @@ -0,0 +1,215 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "components/ui_qrcode.h" +#include "QrCode.hpp" +#include "graphic_log.h" +#include "securec.h" + +using qrcodegen::QrCode; +namespace OHOS { +UIQrcode::UIQrcode() + : width_(0), needDraw_(false), backgroundColor_(Color::White()), qrColor_(Color::Black()), qrcodeVal_(nullptr) +{ + style_ = &(StyleDefault::GetBackgroundTransparentStyle()); + imageInfo_ = {{0}}; +} + +UIQrcode::~UIQrcode() +{ + if (qrcodeVal_ != nullptr) { + UIFree(qrcodeVal_); + qrcodeVal_ = nullptr; + } + + if (imageInfo_.data != nullptr) { + ImageCacheFree(imageInfo_); + imageInfo_.data = nullptr; + } +} + +void UIQrcode::SetQrcodeInfo(const char* val, ColorType backgroundColor, ColorType qrColor) +{ + if (val == nullptr) { + GRAPHIC_LOGE("UIQrcode::SetQrcodeInfo val is null!\n"); + return; + } + uint32_t length = static_cast(strlen(val)); + if ((length > QRCODE_VAL_MAX) || (length == 0)) { + GRAPHIC_LOGE("UIQrcode::SetQrcodeInfo val length is equal 0 or greater than QRCODE_VAL_MAX!\n"); + return; + } + backgroundColor_ = backgroundColor; + qrColor_ = qrColor; + SetQrcodeVal(val, length); + RefreshQrcode(); +} + +void UIQrcode::RefreshQrcode() +{ + Invalidate(); + if (!needDraw_) { + needDraw_ = true; + } +} + +void UIQrcode::SetWidth(int16_t width) +{ + if (GetWidth() != width) { + UIView::SetWidth(width); + RefreshQrcode(); + } +} + +void UIQrcode::SetHeight(int16_t height) +{ + if (GetHeight() != height) { + UIView::SetHeight(height); + RefreshQrcode(); + } +} + +void UIQrcode::ReMeasure() +{ + if (!needDraw_) { + return; + } + needDraw_ = false; + if (qrcodeVal_ == nullptr) { + GRAPHIC_LOGE("UIQrcode::ReMeasure qrcodeVal_ is null!\n"); + return; + } + QrCode qr = QrCode::encodeText(qrcodeVal_, QrCode::Ecc::LOW); + SetImageInfo(qr); + SetSrc(&imageInfo_); +} + +void UIQrcode::SetQrcodeVal(const char* qrcodeVal, uint32_t length) +{ + if (qrcodeVal_ != nullptr) { + UIFree(qrcodeVal_); + qrcodeVal_ = nullptr; + } + + uint32_t len = static_cast(length + 1); + qrcodeVal_ = static_cast(UIMalloc(len)); + if (qrcodeVal_ != nullptr) { + if (memcpy_s(qrcodeVal_, len, qrcodeVal, len) != EOK) { + UIFree(reinterpret_cast(qrcodeVal_)); + qrcodeVal_ = nullptr; + } + } +} + +void UIQrcode::SetImageInfo(qrcodegen::QrCode& qrcode) +{ + int16_t width = GetWidth(); + int16_t height = GetHeight(); + width_ = (width >= height) ? height : width; + if (width_ < qrcode.getSize()) { + GRAPHIC_LOGE("UIQrcode::SetImageInfo width is less than the minimum qrcode width!\n"); + return; + } + imageInfo_.header.width = width; + imageInfo_.header.height = height; + imageInfo_.header.colorMode = ARGB8888; + imageInfo_.dataSize = imageInfo_.header.width * imageInfo_.header.height * QRCODE_FACTOR_NUM; + if (imageInfo_.data != nullptr) { + ImageCacheFree(imageInfo_); + imageInfo_.data = nullptr; + } + imageInfo_.data = reinterpret_cast(ImageCacheMalloc(imageInfo_)); + if (imageInfo_.data == nullptr) { + GRAPHIC_LOGE("UIQrcode::SetImageInfo imageInfo_.data is null!\n"); + return; + } + GenerateQrCode(qrcode); +} + +void UIQrcode::GenerateQrCode(qrcodegen::QrCode& qrcode) +{ + FillQrCodeBackgroundColor(); + + FillQrCodeColor(qrcode); +} + +void UIQrcode::FillQrCodeColor(qrcodegen::QrCode& qrcode) +{ + int32_t qrWidth = qrcode.getSize(); + if (qrWidth <= 0) { + GRAPHIC_LOGE("UIQrcode::FillQrCodeColor generated qrcode size is less or equal 0!\n"); + return; + } + int16_t width = imageInfo_.header.width; + int16_t height = imageInfo_.header.height; + uint16_t outFilePixelPrescaler = width_ / qrWidth; + int32_t offsetX = (width - outFilePixelPrescaler * qrWidth) / 2; // 2: half + int32_t offsetY = (height - outFilePixelPrescaler * qrWidth) / 2; // 2: half + + uint8_t* destData = nullptr; + int64_t oneLinePixel = width * QRCODE_FACTOR_NUM * outFilePixelPrescaler; + int64_t oneLineOffsetPixel = (offsetY * width * QRCODE_FACTOR_NUM) + (offsetX * QRCODE_FACTOR_NUM); + for (int32_t y = 0; y < qrWidth; ++y) { + destData = const_cast(imageInfo_.data) + (oneLinePixel * y) + oneLineOffsetPixel; + for (int32_t x = 0; x < qrWidth; ++x) { + if (qrcode.getModule(x, y)) { + GetDestData(destData, outFilePixelPrescaler); + } + destData += QRCODE_FACTOR_NUM * outFilePixelPrescaler; + } + } +} + +void UIQrcode::FillQrCodeBackgroundColor() +{ + uint8_t* initColorData = const_cast(imageInfo_.data); + *(initColorData + 0) = backgroundColor_.blue; // 0: B channel + *(initColorData + 1) = backgroundColor_.green; // 1: G channel + *(initColorData + 2) = backgroundColor_.red; // 2: R channel + *(initColorData + 3) = OPA_OPAQUE; // 3: Alpha channel + + uint8_t* tempColorData = initColorData; + for (int16_t col = 1; col < imageInfo_.header.width; ++col) { + initColorData += QRCODE_FACTOR_NUM; + if (memcpy_s(initColorData, QRCODE_FACTOR_NUM, tempColorData, QRCODE_FACTOR_NUM) != EOK) { + GRAPHIC_LOGE("UIQrcode::FillQrCodeBackgroundColor memcpy_s failed!\n"); + return; + } + } + initColorData = tempColorData; + int32_t deltaWidth = QRCODE_FACTOR_NUM * imageInfo_.header.width; + for (int16_t row = 1; row < imageInfo_.header.height; ++row) { + initColorData += deltaWidth; + if (memcpy_s(initColorData, deltaWidth, tempColorData, deltaWidth) != EOK) { + GRAPHIC_LOGE("UIQrcode::FillQrCodeBackgroundColor memcpy_s failed!\n"); + return; + } + } +} + +void UIQrcode::GetDestData(uint8_t* destData, int32_t outFilePixelPrescaler) +{ + for (int32_t x = 0; x < outFilePixelPrescaler; ++x) { + uint8_t* tempData = destData + imageInfo_.header.width * QRCODE_FACTOR_NUM * x; + for (int32_t y = 0; y < outFilePixelPrescaler; ++y) { + *(tempData + 0) = qrColor_.blue; // 0: B channel + *(tempData + 1) = qrColor_.green; // 1: G channel + *(tempData + 2) = qrColor_.red; // 2: R channel + *(tempData + 3) = OPA_OPAQUE; // 3: Alpha channel + tempData += QRCODE_FACTOR_NUM; + } + } +} +} // namespace OHOS diff --git a/frameworks/components/ui_radio_button.cpp b/frameworks/components/ui_radio_button.cpp new file mode 100755 index 0000000..6ff60c9 --- /dev/null +++ b/frameworks/components/ui_radio_button.cpp @@ -0,0 +1,166 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "components/ui_radio_button.h" +#include "common/image.h" +#include "components/root_view.h" +#include "components/ui_view_group.h" +#include "draw/draw_arc.h" +#include "draw/draw_image.h" +#include "draw/draw_rect.h" +#include "graphic_log.h" +#include "imgdecode/cache_manager.h" +#include "securec.h" + +namespace OHOS { +UIRadioButton::UIRadioButton() : name_(nullptr), width_(DEFAULT_HOT_WIDTH), height_(DEFAULT_HOT_HEIGHT), + radiusBig_(DEFAULT_RADIUS_BIG), radiusSmall_(DEFAULT_RADIUS_SMALL), + lineWidth_(DEFAULT_LINE_WIDTH) +{ + image_[UNSELECTED].SetSrc(""); + image_[SELECTED].SetSrc(""); + Resize(width_, height_); +} + +UIRadioButton::UIRadioButton(const char* name) : name_(nullptr), width_(DEFAULT_HOT_WIDTH), + height_(DEFAULT_HOT_HEIGHT), radiusBig_(DEFAULT_RADIUS_BIG), + radiusSmall_(DEFAULT_RADIUS_SMALL), lineWidth_(DEFAULT_LINE_WIDTH) +{ + SetName(name); + image_[UNSELECTED].SetSrc(""); + image_[SELECTED].SetSrc(""); + Resize(width_, height_); +} + +bool UIRadioButton::OnClickEvent(const ClickEvent& event) +{ + SetState(SELECTED); + Invalidate(); + UIView* view = this; + while ((view != nullptr) && (view->GetParent() != nullptr)) { + view = view->GetParent(); + } + FindRadioButtonAndChangeState(view); + return UIView::OnClickEvent(event); +} + +void UIRadioButton::CalculateSize() +{ + int16_t width = GetWidth(); + int16_t height = GetHeight(); + if ((width_ == width) && (height_ == height)) { + return; + } + width_ = width; + height_ = height; + int16_t minValue = (width_ > height_) ? height_ : width_; + radiusBig_ = DEFAULT_RADIUS_BIG * minValue / DEFAULT_HOT_WIDTH; + radiusSmall_ = DEFAULT_RADIUS_SMALL * minValue / DEFAULT_HOT_WIDTH; + if (minValue >= DEFAULT_HOT_WIDTH) { + lineWidth_ = DEFAULT_LINE_WIDTH * minValue / DEFAULT_HOT_WIDTH; + } +} + +void UIRadioButton::OnDraw(const Rect& invalidatedArea) +{ + if ((image_[SELECTED].GetSrcType() != IMG_SRC_UNKNOWN) && (image_[UNSELECTED].GetSrcType() != IMG_SRC_UNKNOWN)) { + UICheckBox::OnDraw(invalidatedArea); + } else { + CalculateSize(); + DrawRect::Draw(GetRect(), invalidatedArea, *style_, opaScale_); + Rect contentRect = GetContentRect(); + int16_t dx = width_ >> 1; + int16_t dy = height_ >> 1; + int16_t x = contentRect.GetX() + dx; + int16_t y = contentRect.GetY() + dy; + ArcInfo arcInfoBig = { { x, y }, { 0 }, radiusBig_, 0, CIRCLE_IN_DEGREE, nullptr }; + ArcInfo arcInfoSmall = { { x, y }, { 0 }, radiusSmall_, 0, CIRCLE_IN_DEGREE, nullptr }; + Rect trunc = invalidatedArea; + bool isIntersect = trunc.Intersect(trunc, contentRect); + switch (state_) { + case SELECTED: { + Style styleSelect = StyleDefault::GetBackgroundTransparentStyle(); + styleSelect.lineWidth_ = arcInfoBig.radius; + styleSelect.lineColor_ = Color::GetColorFromRGB(0x1F, 0x71, 0xFF); + if (isIntersect) { + DrawArc::GetInstance()->Draw(arcInfoBig, trunc, styleSelect, OPA_OPAQUE, CapType::CAP_NONE); + } + styleSelect.lineWidth_ = arcInfoSmall.radius; + styleSelect.lineColor_ = Color::White(); + if (isIntersect) { + DrawArc::GetInstance()->Draw(arcInfoSmall, trunc, styleSelect, OPA_OPAQUE, CapType::CAP_NONE); + } + break; + } + case UNSELECTED: { + Style styleUnSelect = StyleDefault::GetBackgroundTransparentStyle(); + styleUnSelect.lineColor_ = Color::White(); + styleUnSelect.lineWidth_ = lineWidth_; + if (isIntersect) { + // 0xa8 : opacity of drawing unselected button arc edge. + DrawArc::GetInstance()->Draw(arcInfoBig, trunc, styleUnSelect, 0xa8, CapType::CAP_NONE); + } + break; + } + default: + break; + } + } +} + +void UIRadioButton::SetName(const char* name) +{ + if (name == nullptr) { + return; + } + if (name_ != nullptr) { + UIFree(name_); + name_ = nullptr; + } + uint32_t nameLen = static_cast(strlen(name) + 1); + if (nameLen > MAX_TEXT_LENGTH) { + return; + } + name_ = static_cast(UIMalloc(nameLen)); + if (name_ != nullptr) { + if (memcpy_s(name_, nameLen, name, nameLen) != EOK) { + UIFree(name_); + name_ = nullptr; + return; + } + } +} + +void UIRadioButton::FindRadioButtonAndChangeState(UIView* view) +{ + if ((view == nullptr) || (name_ == nullptr)) { + return; + } + if (view->IsViewGroup()) { + UIView* childView = static_cast(view)->GetChildrenHead(); + while (childView != nullptr) { + FindRadioButtonAndChangeState(childView); + childView = childView->GetNextSibling(); + } + } + if ((view == this) || (view->GetViewType() != UI_RADIO_BUTTON)) { + return; + } + UIRadioButton* uiRadioButtonInfo = static_cast(view); + if ((uiRadioButtonInfo->GetName() != nullptr) && (strcmp(uiRadioButtonInfo->GetName(), name_) == 0)) { + uiRadioButtonInfo->SetState(UNSELECTED); + } +} +} // namespace OHOS diff --git a/frameworks/components/ui_repeat_button.cpp b/frameworks/components/ui_repeat_button.cpp new file mode 100755 index 0000000..ca2a1d2 --- /dev/null +++ b/frameworks/components/ui_repeat_button.cpp @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "components/ui_repeat_button.h" +#include "components/ui_button.h" + +namespace OHOS { +UIRepeatButton* UIRepeatButton::repeatButton_ = nullptr; + +/** default tick interval 200ms. */ +UIRepeatButton::UIRepeatButton() : ticksInterval_(200), event_({ 0, 0 }), + longPressed_(false), timerRepeatID_(0) {} + +UIRepeatButton::~UIRepeatButton() {} + +void UIRepeatButton::OnDraw(const Rect& invalidatedArea) +{ + UIButton::OnDraw(invalidatedArea); +} + +bool UIRepeatButton::OnReleaseEvent(const ReleaseEvent& event) +{ + if (longPressed_ && (timerRepeatID_ != 0)) { + longPressed_ = false; + } + return UIButton::OnReleaseEvent(event); +} + +bool UIRepeatButton::OnClickEvent(const ClickEvent& event) +{ + SetEvent(event); + return UIButton::OnClickEvent(event); +} + +void UIRepeatButton::HandleTickEvent() +{ + UIButton::OnClickEvent(event_); +} + +bool UIRepeatButton::OnLongPressEvent(const LongPressEvent& event) +{ + longPressed_ = true; + repeatButton_ = this; + return UIButton::OnLongPressEvent(event); +} + +void UIRepeatButton::SetEvent(const ClickEvent& event) +{ + event_ = event; +} +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/components/ui_scroll_view.cpp b/frameworks/components/ui_scroll_view.cpp new file mode 100755 index 0000000..aa16030 --- /dev/null +++ b/frameworks/components/ui_scroll_view.cpp @@ -0,0 +1,417 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "components/ui_scroll_view.h" +#include "dock/focus_manager.h" +#include "draw/draw_rect.h" + +namespace OHOS { +UIScrollView::UIScrollView() + : xSliderPos_({0, 0}), + ySliderPos_({0, 0}), + scrollBarWidth_(DEFAULT_BAR_WIDTH), + xScrollable_(true), + yScrollable_(true), + minScrollBarLen_(DEFAULT_MIN_BAR_LEN), + scrollListener_(nullptr) +{ +#if ENABLE_ROTATE_INPUT + rotateFactor_ = 1; + rotateThreshold_ = 4; // 4: which means 25% of half view size +#endif + direction_ = HORIZONTAL_AND_VERTICAL; + xSlider_.SetVisible(false); + ySlider_.SetVisible(false); + xSlider_.SetStyle(StyleDefault::GetBrightStyle()); + ySlider_.SetStyle(StyleDefault::GetBrightStyle()); +} + +void UIScrollView::OnPostDraw(const Rect& invalidatedArea) +{ + if (!xSlider_.IsVisible() && !ySlider_.IsVisible()) { + return; + } + Rect scrollRect = GetRect(); + if (xSlider_.IsVisible()) { + xSlider_.SetPosition(scrollRect.GetX() + xSliderPos_.x, scrollRect.GetY() + xSliderPos_.y); + xSlider_.OnDraw(invalidatedArea); + } + if (ySlider_.IsVisible()) { + ySlider_.SetPosition(scrollRect.GetX() + ySliderPos_.x, scrollRect.GetY() + ySliderPos_.y); + ySlider_.OnDraw(invalidatedArea); + } +} + +bool UIScrollView::OnDragEvent(const DragEvent& event) +{ + if (scrollAnimator_.GetState() != Animator::STOP) { + UIAbstractScroll::StopAnimator(); + } + Drag(event); + return UIView::OnDragEvent(event); +} + +bool UIScrollView::OnDragEndEvent(const DragEvent& event) +{ + Point last = event.GetPreLastPoint(); + Point current = event.GetLastPoint(); + if ((last.x == current.x) && (last.y == current.y)) { + last = current; + current = event.GetCurrentPos(); + } + + if (!DragThrowAnimator(current, last)) { + if (scrollListener_ && (scrollListener_->GetScrollState() == OnScrollListener::SCROLL_STATE_MOVE)) { + scrollListener_->OnScrollEnd(); + scrollListener_->SetScrollState(OnScrollListener::SCROLL_STATE_STOP); + } + } + return UIView::OnDragEndEvent(event); +} + +void UIScrollView::Drag(const DragEvent& event) +{ + int16_t xDistance = event.GetDeltaX(); + int16_t yDistance = event.GetDeltaY(); + + if (xScrollable_ && xDistance != 0) { + DragXInner(xDistance); + } + if (yScrollable_ && yDistance != 0) { + DragYInner(yDistance); + } +} + +bool UIScrollView::OnPressEvent(const PressEvent& event) +{ + StopAnimator(); + return UIView::OnPressEvent(event); +} + +#if ENABLE_ROTATE_INPUT +bool UIScrollView::OnRotateEvent(const RotateEvent& event) +{ + int16_t tmpRotateLen = static_cast(event.GetRotate() * rotateFactor_); + int16_t midPointX = static_cast(GetWidth() / 2); // 2 : Get the middle point X coord of the view + int16_t midPointY = static_cast(GetHeight() / 2); // 2 : Get the middle point Y coord of the view + Point last, current; + if (!throwDrag_ || ((MATH_ABS(tmpRotateLen) < (midPointX / rotateThreshold_)) && + (MATH_ABS(tmpRotateLen) < (midPointY / rotateThreshold_)))) { + yScrollable_ ? ScrollBy(0, tmpRotateLen) : ScrollBy(tmpRotateLen, 0); + if (event.GetRotate() == 0) { + DragThrowAnimator(Point {0, 0}, Point {0, 0}); + } + } else { + last = Point {midPointX, midPointY}; + yScrollable_ ? (current = Point {midPointX, static_cast(midPointY + tmpRotateLen)}) + : (current = Point {static_cast(midPointX + tmpRotateLen), midPointY}); + DragThrowAnimator(current, last); + } +#if ENABLE_MOTOR + MotorFunc motorFunc = FocusManager::GetInstance()->GetMotorFunc(); + if (motorFunc != nullptr) { + motorFunc(MotorType::MOTOR_TYPE_ONE); + } +#endif + return UIView::OnRotateEvent(event); +} +#endif + +void UIScrollView::ScrollBy(int16_t xDistance, int16_t yDistance) +{ + if (xScrollable_ && xDistance != 0) { + DragXInner(xDistance); + } + if (yScrollable_ && yDistance != 0) { + DragYInner(yDistance); + } + if ((scrollListener_ != nullptr) && (scrollListener_->GetScrollState() == OnScrollListener::SCROLL_STATE_MOVE)) { + scrollListener_->OnScrollEnd(); + scrollListener_->SetScrollState(OnScrollListener::SCROLL_STATE_STOP); + } +} + +bool UIScrollView::DragXInner(int16_t distance) +{ + Rect childRect = GetAllChildRelativeRect(); + int16_t reboundSize = reboundSize_; + if (scrollAnimator_.GetState() != Animator::STOP) { + reboundSize = 0; + } + + if (childRect.GetWidth() <= (GetWidth() - (scrollBlankSize_ << 1))) { + return false; + } + + if (distance > 0) { + if (childRect.GetLeft() > scrollBlankSize_ + reboundSize) { + distance = 0; + } else if ((childRect.GetLeft() + distance) > scrollBlankSize_ + reboundSize) { + distance = scrollBlankSize_ - childRect.GetLeft() + reboundSize; + } + } else { + int16_t childRight = childRect.GetRight(); + int16_t scrollWidth = GetWidth(); + if (yScrollable_ && ySlider_.IsVisible()) { + if (childRight < scrollWidth - ySlider_.GetWidth() - (scrollBlankSize_ + reboundSize)) { + distance = 0; + } else if (childRight + distance < scrollWidth - ySlider_.GetWidth() - (scrollBlankSize_ + reboundSize)) { + distance = scrollWidth - ySlider_.GetWidth() - (scrollBlankSize_ + reboundSize) - childRight; + } + } else { + if (childRight < scrollWidth - (scrollBlankSize_ + reboundSize)) { + distance = 0; + } else if (childRight + distance < scrollWidth - (scrollBlankSize_ + reboundSize)) { + distance = scrollWidth - (scrollBlankSize_ + reboundSize) - childRight - 1; + } + } + } + + return MoveOffset(distance, 0); +} + +bool UIScrollView::DragYInner(int16_t distance) +{ + Rect childRect = GetAllChildRelativeRect(); + int16_t reboundSize = reboundSize_; + if (scrollAnimator_.GetState() != Animator::STOP) { + reboundSize = 0; + } + + if (childRect.GetHeight() <= (GetHeight() - (scrollBlankSize_ << 1))) { + return false; + } + + if (distance > 0) { + if (childRect.GetTop() > scrollBlankSize_ + reboundSize) { + distance = 0; + } else if ((childRect.GetTop() + distance) > scrollBlankSize_ + reboundSize) { + distance = scrollBlankSize_ - childRect.GetTop() + reboundSize; + } + } else { + int16_t childBottom = childRect.GetBottom(); + int16_t scrollHeight = GetHeight(); + if (xScrollable_ && xSlider_.IsVisible()) { + if (childBottom < scrollHeight - xSlider_.GetHeight() - (scrollBlankSize_ + reboundSize)) { + distance = 0; + } else if (childBottom + distance < + scrollHeight - xSlider_.GetHeight() - (scrollBlankSize_ + reboundSize)) { + distance = scrollHeight - xSlider_.GetHeight() - (scrollBlankSize_ + reboundSize) - childBottom; + } + } else { + if (childBottom < scrollHeight - (scrollBlankSize_ + reboundSize)) { + distance = 0; + } else if (childBottom + distance < scrollHeight - (scrollBlankSize_ + reboundSize)) { + distance = scrollHeight - (scrollBlankSize_ + reboundSize) - childBottom - 1; + } + } + } + + return MoveOffset(0, distance); +} + +bool UIScrollView::MoveOffset(int16_t offsetX, int16_t offsetY) +{ + if ((offsetX != 0) || (offsetY != 0)) { + if ((scrollListener_ != nullptr) && + (scrollListener_->GetScrollState() == OnScrollListener::SCROLL_STATE_STOP)) { + scrollListener_->OnScrollStart(); + scrollListener_->SetScrollState(OnScrollListener::SCROLL_STATE_MOVE); + } + UIAbstractScroll::MoveChildByOffset(offsetX, offsetY); + Invalidate(); + RefreshScrollBarPosition(); + return true; + } + return false; +} + +void UIScrollView::RefreshScrollBar() +{ + Rect childRect = GetAllChildRelativeRect(); + if (xScrollable_ && (childRect.GetWidth() <= GetWidth())) { + xSliderPos_.y = GetHeight() - scrollBarWidth_; + xSlider_.SetHeight(scrollBarWidth_); + // y scroll bar is on, x scroll bar width should be group width - scroll bar width + if (yScrollable_) { + xSlider_.SetWidth(GetWidth() - scrollBarWidth_); + } else { + xSlider_.SetWidth(GetWidth()); + } + } + + if (yScrollable_ && (childRect.GetHeight() <= GetHeight())) { + ySliderPos_.x = GetWidth() - scrollBarWidth_; + ySliderPos_.y = 0; + ySlider_.SetWidth(scrollBarWidth_); + // x scroll bar is on, y scroll bar height should be group height - scroll bar width + if (xScrollable_) { + ySlider_.SetHeight(GetHeight() - scrollBarWidth_); + } else { + ySlider_.SetHeight(GetHeight()); + } + } + float multiple; + + // child width is larger than group width, resize the x scroll bar width + if (xScrollable_ && (childRect.GetWidth() > GetWidth()) && (childRect.GetWidth() != 0)) { + int16_t groupWidth = GetWidth(); + int16_t xWidth; + if (yScrollable_) { + multiple = static_cast(groupWidth - scrollBarWidth_) / childRect.GetWidth(); + xWidth = static_cast((groupWidth - scrollBarWidth_) * multiple); + } else { + multiple = static_cast(groupWidth) / childRect.GetWidth(); + xWidth = static_cast(groupWidth * multiple); + } + if (xWidth < minScrollBarLen_) { + xWidth = minScrollBarLen_; + } + + xSliderPos_.x = GetXScrollOffset(childRect); + xSliderPos_.y = GetHeight() - scrollBarWidth_; + xSlider_.SetWidth(xWidth); + xSlider_.SetHeight(scrollBarWidth_); + } + + // child height is larger than group height, resize the y scroll height + if (yScrollable_ && (childRect.GetHeight() > GetHeight()) && (childRect.GetHeight() != 0)) { + int16_t groupHeight = GetHeight(); + int16_t yHeight; + if (xScrollable_) { + multiple = static_cast(groupHeight - scrollBarWidth_) / childRect.GetHeight(); + yHeight = static_cast((groupHeight - scrollBarWidth_) * multiple); + } else { + multiple = static_cast(groupHeight) / childRect.GetHeight(); + yHeight = static_cast(groupHeight * multiple); + } + + // scroll bar may be too small, keep it min size + if (yHeight < minScrollBarLen_) { + yHeight = minScrollBarLen_; + } + + ySliderPos_.x = GetWidth() - scrollBarWidth_; + ySliderPos_.y = GetYScrollOffset(childRect); + ySlider_.SetHeight(yHeight); + ySlider_.SetWidth(scrollBarWidth_); + } +} + +void UIScrollView::RefreshScrollBarPosition() +{ + if (!xSlider_.IsVisible() && !ySlider_.IsVisible()) { + return; + } + Rect childRect = GetAllChildRelativeRect(); + if ((childRect.GetWidth() == 0) || (childRect.GetHeight() == 0)) { + return; + } + if (xScrollable_) { + int16_t xOffset = GetXScrollOffset(childRect); + xSliderPos_.x = xOffset; + Invalidate(); + } + if (yScrollable_) { + int16_t yOffset = GetYScrollOffset(childRect); + ySliderPos_.y = yOffset; + Invalidate(); + } +} + +int16_t UIScrollView::GetXScrollOffset(const Rect& childRect) +{ + Rect scrollRect = GetRelativeRect(); + int16_t xOffset; + int16_t scrollBarOffset = 0; + + if (yScrollable_) { + scrollBarOffset = scrollBarWidth_; + } + + int16_t childRectLeft = childRect.GetLeft(); + int16_t childRectWidth = childRect.GetWidth(); + int16_t scrollRectWidth = scrollRect.GetWidth(); + int16_t xSliderWidth = xSlider_.GetWidth(); + if ((childRectLeft >= 0) || (childRectWidth - scrollRectWidth + scrollBarOffset == 0)) { + xOffset = 0; + } else { + float multiple = static_cast(scrollRectWidth - scrollBarOffset - xSliderWidth) / + (childRectWidth - scrollRectWidth + scrollBarOffset); + xOffset = static_cast(-childRectLeft * multiple); + } + return xOffset; +} + +int16_t UIScrollView::GetYScrollOffset(const Rect& childRect) +{ + Rect scrollRect = GetRelativeRect(); + int16_t yOffset; + int16_t scrollBarOffset = 0; + + if (xScrollable_) { + scrollBarOffset = scrollBarWidth_; + } + + int16_t childRectTop = childRect.GetTop(); + int16_t childRectHeight = childRect.GetHeight(); + int16_t scrollRectHeight = scrollRect.GetHeight(); + int16_t ySliderHeight = ySlider_.GetHeight(); + if ((childRectTop >= 0) || (childRectHeight - scrollRectHeight + scrollBarOffset == 0)) { + yOffset = 0; + } else { + float multiple = static_cast(scrollRectHeight - scrollBarOffset - ySliderHeight) / + (childRectHeight - scrollRectHeight + scrollBarOffset); + yOffset = static_cast(-childRectTop * multiple); + } + return yOffset; +} + +void UIScrollView::OnChildChanged() +{ + RefreshScrollBar(); +} + +void UIScrollView::CalculateReboundDistance(int16_t& dragDistanceX, int16_t& dragDistanceY) +{ + Rect rect = GetAllChildRelativeRect(); + int16_t top = rect.GetTop(); + int16_t bottom = rect.GetBottom(); + int16_t scrollHeight = GetHeight(); + int16_t left = rect.GetLeft(); + int16_t right = rect.GetRight(); + int16_t scrollWidth = GetWidth(); + if (scrollBlankSize_ < top) { + dragDistanceY = scrollBlankSize_ - top; + } else if (bottom < scrollHeight - 1) { + dragDistanceY = scrollHeight - scrollBlankSize_ - bottom - 1; + } + + if (scrollBlankSize_ < left) { + dragDistanceX = scrollBlankSize_ - left; + } else if (right < scrollWidth - 1) { + dragDistanceX = scrollWidth - scrollBlankSize_ - right - 1; + } +} + +void UIScrollView::StopAnimator() +{ + if ((scrollListener_ != nullptr) && (scrollListener_->GetScrollState() == OnScrollListener::SCROLL_STATE_MOVE)) { + scrollListener_->OnScrollEnd(); + scrollListener_->SetScrollState(OnScrollListener::SCROLL_STATE_STOP); + } + UIAbstractScroll::StopAnimator(); +} +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/components/ui_slider.cpp b/frameworks/components/ui_slider.cpp new file mode 100755 index 0000000..3e1224d --- /dev/null +++ b/frameworks/components/ui_slider.cpp @@ -0,0 +1,299 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "components/ui_slider.h" +#include "common/image.h" +#include "dock/focus_manager.h" +#include "draw/draw_image.h" +#include "draw/draw_rect.h" +#include "graphic_log.h" +#include "imgdecode/cache_manager.h" +#include "themes/theme_manager.h" + +namespace OHOS { +UISlider::UISlider() + : knobWidth_(0), knobWidthSetFlag_(false), knobStyleAllocFlag_(false), knobImage_(nullptr), listener_(nullptr) +{ + touchable_ = true; + draggable_ = true; + dragParentInstead_ = false; + Theme* theme = ThemeManager::GetInstance().GetCurrent(); + if (theme != nullptr) { + knobStyle_ = &(theme->GetSliderKnobStyle()); + } else { + knobStyle_ = &(StyleDefault::GetSliderKnobStyle()); + } +} + +UISlider::~UISlider() +{ + if (knobImage_ != nullptr) { + delete knobImage_; + knobImage_ = nullptr; + } + + if (knobStyleAllocFlag_) { + delete knobStyle_; + knobStyle_ = nullptr; + knobStyleAllocFlag_ = false; + } +} + +void UISlider::SetKnobStyle(const Style& style) +{ + if (!knobStyleAllocFlag_) { + knobStyle_ = new Style; + if (knobStyle_ == nullptr) { + GRAPHIC_LOGE("new Style fail"); + return; + } + knobStyleAllocFlag_ = true; + } + *knobStyle_ = style; +} + +void UISlider::SetKnobStyle(uint8_t key, int64_t value) +{ + if (!knobStyleAllocFlag_) { + knobStyle_ = new Style(*knobStyle_); + if (knobStyle_ == nullptr) { + GRAPHIC_LOGE("new Style fail"); + return; + } + knobStyleAllocFlag_ = true; + } + knobStyle_->SetStyle(key, value); +} + +const Style& UISlider::GetKnobStyle() const +{ + return *knobStyle_; +} + +int64_t UISlider::GetKnobStyle(uint8_t key) const +{ + return knobStyle_->GetStyle(key); +} + +int32_t UISlider::CalculateCurrentValue(int16_t length, int16_t totalLength) +{ + if (totalLength != 0) { + return static_cast(rangeMin_ + (static_cast(rangeMax_) - rangeMin_) * length / totalLength); + } + return 0; +} + +int32_t UISlider::UpdateCurrentValue(const Point& knobPosition) +{ + Point startPoint; + Rect rect = GetOrigRect(); + startPoint.x = rect.GetLeft() + style_->borderWidth_ + style_->paddingLeft_; + startPoint.y = rect.GetTop() + style_->borderWidth_ + style_->paddingTop_; + + int32_t value = curValue_; + switch (direction_) { + case Direction::DIR_LEFT_TO_RIGHT: + if (knobPosition.x <= startPoint.x) { + value = rangeMin_; + } else if (knobPosition.x >= startPoint.x + progressWidth_) { + value = rangeMax_; + } else { + value = CalculateCurrentValue(knobPosition.x - startPoint.x, progressWidth_); + } + break; + case Direction::DIR_RIGHT_TO_LEFT: + if (knobPosition.x <= startPoint.x) { + value = rangeMax_; + } else if (knobPosition.x >= startPoint.x + progressWidth_) { + value = rangeMin_; + } else { + value = CalculateCurrentValue(startPoint.x + progressWidth_ - knobPosition.x, progressWidth_); + } + break; + case Direction::DIR_BOTTOM_TO_TOP: + if (knobPosition.y <= startPoint.y) { + value = rangeMax_; + } else if (knobPosition.y >= startPoint.y + progressHeight_) { + value = rangeMin_; + } else { + value = CalculateCurrentValue(startPoint.y + progressHeight_ - knobPosition.y, progressHeight_); + } + break; + case Direction::DIR_TOP_TO_BOTTOM: + if (knobPosition.y <= startPoint.y) { + value = rangeMin_; + } else if (knobPosition.y >= startPoint.y + progressHeight_) { + value = rangeMax_; + } else { + value = CalculateCurrentValue(knobPosition.y - startPoint.y, progressHeight_); + } + break; + default: + GRAPHIC_LOGW("UISlider::UpdateCurrentValue Direction error!\n"); + } + SetValue(value); + return value; +} + +bool UISlider::OnClickEvent(const ClickEvent& event) +{ + Point knobPosition = event.GetCurrentPos(); + int32_t value = UpdateCurrentValue(knobPosition); + if (listener_ != nullptr) { + listener_->OnChange(value); + } + bool ret = UIView::OnClickEvent(event); + Invalidate(); + return ret; +} + +bool UISlider::OnDragEvent(const DragEvent& event) +{ + Point knobPosition = event.GetCurrentPos(); + int32_t value = UpdateCurrentValue(knobPosition); + if (listener_ != nullptr) { + listener_->OnChange(value); + } + Invalidate(); + return UIView::OnDragEvent(event); +} + +bool UISlider::OnDragEndEvent(const DragEvent& event) +{ + Point knobPosition = event.GetCurrentPos(); + int32_t value = UpdateCurrentValue(knobPosition); + if (listener_ != nullptr) { + listener_->OnChange(value); + listener_->OnRelease(value); + } + Invalidate(); + return UIView::OnDragEndEvent(event); +} + +#if ENABLE_ROTATE_INPUT +bool UISlider::OnRotateEvent(const RotateEvent& event) +{ + if (event.GetRotate() == 0) { + return false; + } + int32_t tmp = event.GetRotate() * rotateFactor_; + SetValue(curValue_ + tmp); +#if ENABLE_MOTOR + MotorFunc motorFunc = FocusManager::GetInstance()->GetMotorFunc(); + if (motorFunc != nullptr) { + motorFunc(MotorType::MOTOR_TYPE_TWO); + } +#endif + return UIView::OnRotateEvent(event); +} +#endif + +int16_t UISlider::GetKnobWidth() +{ + if (!knobWidthSetFlag_) { + if ((direction_ == Direction::DIR_LEFT_TO_RIGHT) || (direction_ == Direction::DIR_RIGHT_TO_LEFT)) { + knobWidth_ = progressHeight_; + } else { + knobWidth_ = progressWidth_; + } + } + return knobWidth_; +} + +void UISlider::SetImage(const ImageInfo* backgroundImage, const ImageInfo* foregroundImage, const ImageInfo* knobImage) +{ + if (!InitImage()) { + return; + } + backgroundImage_->SetSrc(backgroundImage); + foregroundImage_->SetSrc(foregroundImage); + knobImage_->SetSrc(knobImage); +} + +void UISlider::SetImage(const char* backgroundImage, const char* foregroundImage, const char* knobImage) +{ + if (!InitImage()) { + return; + } + backgroundImage_->SetSrc(backgroundImage); + foregroundImage_->SetSrc(foregroundImage); + knobImage_->SetSrc(knobImage); +} + +void UISlider::DrawKnob(const Rect& invalidatedArea, const Rect& foregroundRect) +{ + int16_t halfKnobWidth = GetKnobWidth() >> 1; + int16_t offset; + Rect knobBar; + switch (direction_) { + case Direction::DIR_LEFT_TO_RIGHT: { + offset = (knobWidth_ - progressHeight_) >> 1; + knobBar.SetRect(foregroundRect.GetRight() - halfKnobWidth, foregroundRect.GetTop() - offset, + foregroundRect.GetRight() + halfKnobWidth, foregroundRect.GetBottom() + offset); + break; + } + case Direction::DIR_RIGHT_TO_LEFT: { + offset = (knobWidth_ - progressHeight_) >> 1; + knobBar.SetRect(foregroundRect.GetLeft() - halfKnobWidth, foregroundRect.GetTop() - offset, + foregroundRect.GetLeft() + halfKnobWidth, foregroundRect.GetBottom() + offset); + break; + } + case Direction::DIR_BOTTOM_TO_TOP: { + offset = (knobWidth_ - progressWidth_) >> 1; + knobBar.SetRect(foregroundRect.GetLeft() - offset, foregroundRect.GetTop() - halfKnobWidth, + foregroundRect.GetRight() + offset, foregroundRect.GetTop() + halfKnobWidth); + break; + } + case Direction::DIR_TOP_TO_BOTTOM: { + offset = (knobWidth_ - progressWidth_) >> 1; + knobBar.SetRect(foregroundRect.GetLeft() - offset, foregroundRect.GetBottom() - halfKnobWidth, + foregroundRect.GetRight() + offset, foregroundRect.GetBottom() + halfKnobWidth); + break; + } + default: { + GRAPHIC_LOGW("UISlider::DrawKnob Direction error!\n"); + } + } + DrawValidRect(knobImage_, knobBar, invalidatedArea, *knobStyle_, 0); +} + +void UISlider::OnDraw(const Rect& invalidatedArea) +{ + DrawRect::Draw(GetOrigRect(), invalidatedArea, *style_, opaScale_); + + Rect trunc(invalidatedArea); + if (trunc.Intersect(trunc, GetOrigRect())) { + DrawBackground(trunc); + Rect foregroundRect; + DrawForeground(trunc, foregroundRect); + DrawKnob(trunc, foregroundRect); + } +} + +bool UISlider::InitImage() +{ + if (!UIAbstractProgress::InitImage()) { + return false; + } + if (knobImage_ == nullptr) { + knobImage_ = new Image(); + if (knobImage_ == nullptr) { + GRAPHIC_LOGE("new Image fail"); + return false; + } + } + return true; +} +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/components/ui_surface_view.cpp b/frameworks/components/ui_surface_view.cpp new file mode 100755 index 0000000..2b6abc3 --- /dev/null +++ b/frameworks/components/ui_surface_view.cpp @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "components/ui_surface_view.h" + +#include + +#include "draw/draw_rect.h" +#include "draw/draw_utils.h" +#include "graphic_log.h" +#include "surface_buffer.h" + +namespace OHOS { +UISurfaceView::UISurfaceView() +{ + surface_ = Surface::CreateSurface(); + if (surface_ == nullptr) { + GRAPHIC_LOGE("UISurfaceView::UISurfaceView surface create failed\n"); + return; + } + surface_->SetWidthAndHeight(GetWidth(), GetHeight()); + surface_->SetQueueSize(DEFAULT_QUEUE_SIZE); + surface_->SetFormat(IMAGE_PIXEL_FORMAT_ARGB8888); +} + +UISurfaceView::~UISurfaceView() +{ + if (surface_ != nullptr) { + delete surface_; + surface_ = nullptr; + } +} + +void UISurfaceView::SetPosition(int16_t x, int16_t y) +{ + UIView::SetPosition(x, y); + if (surface_ == nullptr) { + GRAPHIC_LOGE("UISurfaceView::SetPosition surface is null\n"); + return; + } + x = GetRect().GetLeft(); + y = GetRect().GetTop(); + surface_->SetUserData(REGION_POSITION_X, std::to_string(x)); + surface_->SetUserData(REGION_POSITION_Y, std::to_string(y)); +} + +void UISurfaceView::SetPosition(int16_t x, int16_t y, int16_t width, int16_t height) +{ + UIView::SetPosition(x, y, width, height); + if (surface_ == nullptr) { + GRAPHIC_LOGE("UISurfaceView::SetPosition surface is null\n"); + return; + } + x = GetRect().GetLeft(); + y = GetRect().GetTop(); + surface_->SetUserData(REGION_POSITION_X, std::to_string(x)); + surface_->SetUserData(REGION_POSITION_Y, std::to_string(y)); + surface_->SetUserData(REGION_WIDTH, std::to_string(width)); + surface_->SetUserData(REGION_HEIGHT, std::to_string(height)); +} + +void UISurfaceView::Resize(int16_t width, int16_t height) +{ + UIView::Resize(width, height); + if (surface_ == nullptr) { + GRAPHIC_LOGE("UISurfaceView::Resize surface is null\n"); + return; + } + surface_->SetUserData(REGION_WIDTH, std::to_string(width)); + surface_->SetUserData(REGION_HEIGHT, std::to_string(height)); +} + +void UISurfaceView::SetWidth(int16_t width) +{ + UIView::SetWidth(width); + if (surface_ == nullptr) { + GRAPHIC_LOGE("UISurfaceView::SetWidth surface is null\n"); + return; + } + surface_->SetUserData(REGION_WIDTH, std::to_string(width)); +} + +void UISurfaceView::SetHeight(int16_t height) +{ + UIView::SetHeight(height); + if (surface_ == nullptr) { + GRAPHIC_LOGE("UISurfaceView::SetHeight surface is null\n"); + return; + } + surface_->SetUserData(REGION_HEIGHT, std::to_string(height)); +} + +void UISurfaceView::SetX(int16_t x) +{ + UIView::SetX(x); + if (surface_ == nullptr) { + GRAPHIC_LOGE("UISurfaceView::SetX surface is null\n"); + return; + } + x = GetRect().GetLeft(); + surface_->SetUserData(REGION_POSITION_X, std::to_string(x)); +} + +void UISurfaceView::SetY(int16_t y) +{ + UIView::SetY(y); + if (surface_ == nullptr) { + GRAPHIC_LOGE("UISurfaceView::SetY surface is null\n"); + return; + } + y = GetRect().GetTop(); + surface_->SetUserData(REGION_POSITION_Y, std::to_string(y)); +} + +Surface* UISurfaceView::GetSurface() const +{ + return surface_; +} + +bool UISurfaceView::OnPreDraw(Rect& invalidatedArea) const +{ + // need fill transpant color + return false; +} + +void UISurfaceView::OnDraw(const Rect& invalidatedArea) +{ + Draw(invalidatedArea); +} + +void UISurfaceView::Draw(const Rect& invalidatedArea) +{ + SurfaceBuffer* acquireBuffer = (surface_ != nullptr) ? surface_->AcquireBuffer() : nullptr; + if (acquireBuffer != nullptr) { + GRAPHIC_LOGE("UISurfaceView::Draw acquireBufferVirAddr=%p \n", acquireBuffer->GetVirAddr()); + // fill with buffer + DrawUtils::GetInstance()->DrawWithBuffer(GetRect(), invalidatedArea, + reinterpret_cast(acquireBuffer->GetVirAddr())); + surface_->ReleaseBuffer(acquireBuffer); + } else { + // fill with transpant color + DrawUtils::GetInstance()->DrawTranspantArea(GetRect(), invalidatedArea); + } +} +} // namespace OHOS diff --git a/frameworks/components/ui_swipe_view.cpp b/frameworks/components/ui_swipe_view.cpp new file mode 100755 index 0000000..e94e174 --- /dev/null +++ b/frameworks/components/ui_swipe_view.cpp @@ -0,0 +1,480 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "components/ui_swipe_view.h" +#include "dock/focus_manager.h" + +namespace OHOS { +UISwipeView::UISwipeView(uint8_t direction) + : swipeListener_(nullptr), + curIndex_(0), + blankSize_(DEFAULT_BLANK_SIZE), + curView_(nullptr), + loop_(false) +{ +#if ENABLE_ROTATE_INPUT + rotateFactor_ = 1; +#endif + direction_ = direction; + AnimatorManager::GetInstance()->Add(&scrollAnimator_); + tickTime_ = ANIMATOR_TIME; + swipeAccCoefficient_ = DRAG_ACC_FACTOR; +} + +UISwipeView::~UISwipeView() +{ + AnimatorManager::GetInstance()->Remove(&scrollAnimator_); +} + +void UISwipeView::Add(UIView* view) +{ + if (view == nullptr) { + return; + } + view->SetDragParentInstead(true); + UIViewGroup::Add(view); + SortChild(); + Invalidate(); +} + +void UISwipeView::Insert(UIView* prevView, UIView* insertView) +{ + if (insertView == nullptr) { + return; + } + insertView->SetDragParentInstead(true); + UIViewGroup::Insert(prevView, insertView); + SortChild(); + Invalidate(); +} + +void UISwipeView::Remove(UIView* view) +{ + if (view == nullptr) { + return; + } + UIViewGroup::Remove(view); + SortChild(); + Invalidate(); +} + +void UISwipeView::SetCurrentPage(uint16_t index, bool needAnimator) +{ + SwitchToPage(index, needAnimator); + Invalidate(); +} + +bool UISwipeView::DragXInner(int16_t distance) +{ + if (distance == 0) { + return true; + } + if (!loop_) { + if ((distance > 0) && (childrenHead_ != nullptr)) { + if (childrenHead_->GetX() >= blankSize_) { + distance = 0; + } else if (childrenHead_ && (childrenHead_->GetX() + distance > blankSize_)) { + distance = blankSize_ - childrenHead_->GetX(); + } + } else if (childrenTail_ != nullptr) { + int16_t width = GetWidth(); + if (childrenTail_->GetRelativeRect().GetRight() < width - blankSize_) { + distance = 0; + } else if (width - (childrenTail_->GetX() + childrenTail_->GetWidth() + distance) > blankSize_) { + distance = width - blankSize_ - childrenTail_->GetX() - childrenTail_->GetWidth(); + } + } + } + CalculateInvalidate(); + MoveChildByOffset(distance, 0); + CalculateInvalidate(); + return true; +} + +bool UISwipeView::DragYInner(int16_t distance) +{ + if (distance == 0) { + return true; + } + if (!loop_) { + if ((distance > 0) && (childrenHead_ != nullptr)) { + if (childrenHead_->GetY() >= blankSize_) { + distance = 0; + } else if ((childrenHead_ != nullptr) && (childrenHead_->GetY() + distance > blankSize_)) { + distance = blankSize_ - childrenHead_->GetY(); + } + } else if (childrenTail_ != nullptr) { + int16_t height = GetHeight(); + if (childrenTail_->GetRelativeRect().GetBottom() < height - blankSize_) { + distance = 0; + } else if (height - (childrenTail_->GetY() + childrenTail_->GetHeight() + distance) > blankSize_) { + distance = height - blankSize_ - childrenTail_->GetY() - childrenTail_->GetHeight(); + } + } + } + CalculateInvalidate(); + MoveChildByOffset(0, distance); + CalculateInvalidate(); + return true; +} + +bool UISwipeView::OnDragEvent(const DragEvent& event) +{ + UIView* currentView = GetViewByIndex(curIndex_); + if (currentView == nullptr) { + return UIView::OnDragEvent(event); + } + if (scrollAnimator_.GetState() != Animator::STOP) { + UIAbstractScroll::StopAnimator(); + } + + if (direction_ == HORIZONTAL) { + DragXInner(event.GetDeltaX()); + RefreshDeltaY(event.GetDeltaX()); + } else { + DragYInner(event.GetDeltaY()); + RefreshDeltaY(event.GetDeltaY()); + } + return UIView::OnDragEvent(event); +} + +bool UISwipeView::OnDragEndEvent(const DragEvent& event) +{ + int16_t distance = 0; + if (direction_ == HORIZONTAL) { + distance = event.GetCurrentPos().x - event.GetPreLastPoint().x; + } else { + distance = event.GetCurrentPos().y - event.GetPreLastPoint().y; + } + RefreshCurrentView(distance); + + if (curView_ == nullptr) { + return UIView::OnDragEndEvent(event); + } + + SwitchToPage(curIndex_); + + Invalidate(); + return UIView::OnDragEndEvent(event); +} + +#if ENABLE_ROTATE_INPUT +bool UISwipeView::OnRotateEvent(const RotateEvent& event) +{ + if (event.GetRotate() != 0) { + // 4 : need to fit for the device + if (MATH_ABS(event.GetRotate()) > blankSize_ / (4 * static_cast(rotateFactor_))) { + SwitchToPage(curIndex_ - event.GetRotate()); + } else { + int16_t tmp = event.GetRotate() * rotateFactor_; + DragXInner(tmp); + RefreshCurrentView(tmp); + } + } else { + SwitchToPage(curIndex_); +#if ENABLE_MOTOR + MotorFunc motorFunc = FocusManager::GetInstance()->GetMotorFunc(); + if (motorFunc != nullptr) { + motorFunc(MotorType::MOTOR_TYPE_ONE); + } +#endif + } + return UIView::OnRotateEvent(event); +} +#endif + +UIView* UISwipeView::GetViewByIndex(uint16_t index) const +{ + UIView* child = childrenHead_; + while (child != nullptr) { + if (child->GetViewIndex() == index) { + return child; + } + child = child->GetNextSibling(); + } + return nullptr; +} + +void UISwipeView::SetAnimatorTime(uint16_t time) +{ + tickTime_ = time / DEFAULT_TASK_PERIOD; + if (tickTime_ == 0) { + tickTime_ = 1; + } + animatorCallback_.SetDragTimes(tickTime_); +} + +void UISwipeView::SwitchToPage(int16_t dst, bool needAnimator) +{ + if (isNeedLoop()) { + dst = (dst + childrenNum_) % childrenNum_; + } else if (dst < 0) { + dst = 0; + } else if (dst >= childrenNum_) { + dst = childrenNum_ - 1; + } + + UIView* dstView = GetViewByIndex(dst); + if (dstView == nullptr) { + return; + } + curIndex_ = dst; + int16_t xOffset = 0; + int16_t yOffset = 0; + + if (direction_ == HORIZONTAL) { + if (alignMode_ == ALIGN_LEFT) { + xOffset = -dstView->GetX(); + } else if (alignMode_ == ALIGN_RIGHT) { + xOffset = GetWidth() - (dstView->GetX() + dstView->GetWidth()); + } else { + xOffset = (GetWidth() >> 1) - (dstView->GetX() + (dstView->GetWidth() >> 1)); + } + } else { + yOffset = (GetHeight() >> 1) - (dstView->GetY() + (dstView->GetHeight() >> 1)); + } + + if ((xOffset != 0) || (yOffset != 0)) { + if (scrollAnimator_.GetState() != Animator::STOP) { + scrollAnimator_.Stop(); + } + if (needAnimator) { + animatorCallback_.SetDragTimes(tickTime_); + animatorCallback_.SetDragStartValue(0, 0); + animatorCallback_.SetDragEndValue(xOffset, yOffset); + scrollAnimator_.Start(); + } else { + MoveChildByOffset(xOffset, yOffset); + } + } +} + +void UISwipeView::StopAnimator() +{ + UIAbstractScroll::StopAnimator(); + if (swipeListener_ != nullptr) { + swipeListener_->OnSwipe(*this); + } +} + +void UISwipeView::SortChild() +{ + if (childrenHead_ == nullptr) { + return; + } + int16_t index = 0; + UIView* pre = childrenHead_; + UIView* next = childrenHead_->GetNextSibling(); + if (direction_ == HORIZONTAL) { + pre->SetX(0); + } else { + pre->SetY(0); + } + pre->SetViewIndex(index); + index++; + + while (next != nullptr) { + if (direction_ == HORIZONTAL) { + next->SetX(pre->GetX() + pre->GetWidth()); + } else { + next->SetY(pre->GetY() + pre->GetHeight()); + } + pre = next; + next->SetViewIndex(index); + next = next->GetNextSibling(); + index++; + } + bool tmpLoop = loop_; + loop_ = false; + SwitchToPage(curIndex_, false); + loop_ = tmpLoop; +} + +void UISwipeView::RefreshCurrentViewInner(int16_t distance, int16_t (UIView::*pfnGetXOrY)() const, + int16_t(UIView::*pfnGetWidthOrHeight)()) +{ + if (childrenHead_ == nullptr) { + curIndex_ = 0; + curView_ = nullptr; + return; + } + + curIndex_ = 0; + curView_ = nullptr; + + uint16_t swipeMid; + if (alignMode_ == ALIGN_LEFT) { + swipeMid = 0; + } else if (alignMode_ == ALIGN_RIGHT) { + swipeMid = (this->*pfnGetWidthOrHeight)(); + } else { + swipeMid = (this->*pfnGetWidthOrHeight)() >> 1; + } + UIView* view = childrenHead_; + + if ((childrenHead_->*pfnGetXOrY)() > swipeMid) { + curIndex_ = childrenHead_->GetViewIndex(); + curView_ = childrenHead_; + } else if ((childrenTail_->*pfnGetXOrY)() + (childrenHead_->*pfnGetWidthOrHeight)() < swipeMid) { + curIndex_ = childrenTail_->GetViewIndex(); + curView_ = childrenTail_; + } else { + while (view != nullptr) { + if ((swipeMid >= (view->*pfnGetXOrY)()) && + (swipeMid <= (view->*pfnGetXOrY)() + (view->*pfnGetWidthOrHeight)())) { + curIndex_ = view->GetViewIndex(); + curView_ = view; + break; + } + view = view->GetNextSibling(); + } + } + if (curView_ == nullptr) { + return; + } + + int16_t accelerationOffset = GetMaxDeltaY() * GetSwipeACCLevel() / DRAG_ACC_FACTOR; + if (distance < 0) { + /* + * 7, 10 : Check whether the current view is dragged by more than 1/5, + * that is, the x or y coordinate plus 7/10 width or height. + */ + if (((curView_->*pfnGetXOrY)() + ((curView_->*pfnGetWidthOrHeight)() >> 1) < swipeMid) && + ((curView_->*pfnGetXOrY)() + ((curView_->*pfnGetWidthOrHeight)() * 7 / 10) - + accelerationOffset < swipeMid)) { + curIndex_++; + } + } else if (distance > 0) { + /* + * 3, 10 : Check whether the current view is dragged by more than 1/5, + * that is, the x or y coordinate plus 3/10 width or height. + */ + if (((curView_->*pfnGetXOrY)() + ((curView_->*pfnGetWidthOrHeight)() >> 1) > swipeMid) && + ((curView_->*pfnGetXOrY)() + ((curView_->*pfnGetWidthOrHeight)() * 3 / 10) + + accelerationOffset > swipeMid)) { + curIndex_--; + } + } else { + if (alignMode_ == ALIGN_LEFT) { + if (((curView_->*pfnGetXOrY)() + ((curView_->*pfnGetWidthOrHeight)() >> 1) < swipeMid)) { + curIndex_++; + } + } else if (alignMode_ == ALIGN_RIGHT) { + if ((curView_->*pfnGetXOrY)() + ((curView_->*pfnGetWidthOrHeight)() >> 1) > swipeMid) { + curIndex_--; + } + } + } +} + +void UISwipeView::RefreshCurrentView(int16_t distance) +{ + if (direction_ == HORIZONTAL) { + RefreshCurrentViewInner(distance, &UIView::GetX, &UIView::GetWidth); + } else { + RefreshCurrentViewInner(distance, &UIView::GetY, &UIView::GetHeight); + } +} + +void UISwipeView::MoveChildByOffset(int16_t xOffset, int16_t yOffset) +{ + UIViewGroup::MoveChildByOffset(xOffset, yOffset); + if (direction_ == HORIZONTAL) { + while (isNeedLoop() && (childrenHead_->GetX() > 0)) { + MoveLastChildToFirst(); + } + while (isNeedLoop() && (childrenTail_->GetX() + childrenTail_->GetWidth() < GetWidth())) { + MoveFirstChildToLast(); + } + } else { + while (isNeedLoop() && (childrenHead_->GetY() > 0)) { + MoveLastChildToFirst(); + } + while (isNeedLoop() && (childrenTail_->GetY() + childrenTail_->GetHeight() < GetHeight())) { + MoveFirstChildToLast(); + } + } +} + +bool UISwipeView::isNeedLoop() +{ + if (!loop_ || (childrenHead_ == nullptr) || (childrenTail_ == nullptr)) { + return false; + } + Rect childRect = GetAllChildRelativeRect(); + if (direction_ == HORIZONTAL) { + if ((childRect.GetWidth() - childrenHead_->GetWidth() >= GetWidth()) && + (childRect.GetWidth() - childrenTail_->GetWidth() >= GetWidth())) { + return true; + } + } else { + if ((childRect.GetHeight() - childrenHead_->GetHeight() >= GetHeight()) && + (childRect.GetHeight() - childrenTail_->GetHeight() >= GetHeight())) { + return true; + } + } + return false; +} + +void UISwipeView::MoveFirstChildToLast() +{ + if ((childrenTail_ == nullptr) || (childrenHead_ == nullptr)) { + return; + } + if (direction_ == HORIZONTAL) { + childrenHead_->SetX(childrenTail_->GetX() + childrenTail_->GetWidth()); + } else { + childrenHead_->SetY(childrenTail_->GetY() + childrenTail_->GetHeight()); + } + UIView* head = childrenHead_; + UIViewGroup::Remove(childrenHead_); + UIViewGroup::Add(head); +} + +void UISwipeView::MoveLastChildToFirst() +{ + if ((childrenTail_ == nullptr) || (childrenHead_ == nullptr)) { + return; + } + if (direction_ == HORIZONTAL) { + childrenTail_->SetX(childrenHead_->GetX() - childrenTail_->GetWidth()); + } else { + childrenTail_->SetY(childrenHead_->GetY() - childrenTail_->GetHeight()); + } + UIView* last = childrenTail_; + UIViewGroup::Remove(childrenTail_); + UIViewGroup::Insert(nullptr, last); +} + +void UISwipeView::CalculateInvalidate() +{ + Rect swipeRect(0, 0, GetRelativeRect().GetWidth() - 1, GetRelativeRect().GetHeight() - 1); + UIView* view = childrenHead_; + bool isFound = false; + while (view != nullptr) { + Rect rect = view->GetRelativeRect(); + if (rect.IsIntersect(swipeRect)) { + if (view->IsVisible() && (view->GetOpaScale() != OPA_TRANSPARENT)) { + view->Invalidate(); + } + isFound = true; + } else if (isFound) { + return; + } + + view = view->GetNextSibling(); + } +} +} // namespace OHOS diff --git a/frameworks/components/ui_texture_mapper.cpp b/frameworks/components/ui_texture_mapper.cpp new file mode 100755 index 0000000..636ecee --- /dev/null +++ b/frameworks/components/ui_texture_mapper.cpp @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "components/ui_texture_mapper.h" + +namespace OHOS { +void UITextureMapper::TextureMapperAnimatorCallback::Callback(UIView* view) +{ + if (view == nullptr) { + return; + } + UITextureMapper* mapper = static_cast(view); + mapper->Callback(); +} + +void UITextureMapper::TextureMapperAnimatorCallback::OnStop(UIView& view) +{ + UITextureMapper& mapper = static_cast(view); + if (mapper.listener_ != nullptr) { + mapper.listener_->OnAnimatorStop(view); + } +} + +UITextureMapper::UITextureMapper() + : animator_(&animatorCallback_, this, 0, false), + listener_(nullptr), + pivot_(0, 0), + rotateCur_(0), + rotateStart_(0), + rotateEnd_(0), + scaleCur_(SCALE_CONVERTION), + scaleStart_(SCALE_CONVERTION), + scaleEnd_(SCALE_CONVERTION), + delayTime_(0), + easingFunc_(EasingEquation::LinearEaseNone) +{ + AnimatorManager::GetInstance()->Add(&animator_); +} + +UITextureMapper::~UITextureMapper() +{ + AnimatorManager::GetInstance()->Remove(&animator_); +} + +void UITextureMapper::Start() +{ + rotateStart_ = rotateCur_; + scaleStart_ = scaleCur_; + animator_.Start(); +} + +void UITextureMapper::Cancel() +{ + animator_.Stop(); +} + +void UITextureMapper::Reset() +{ + Invalidate(); + ResetTransParameter(); + Invalidate(); +} + +void UITextureMapper::Callback() +{ + uint16_t curTime = animator_.GetRunTime(); + if (curTime >= delayTime_) { + uint16_t actualTime = curTime - delayTime_; + uint16_t durationTime = animator_.GetTime() - delayTime_; + + if (scaleStart_ != scaleEnd_) { + scaleCur_ = easingFunc_(scaleStart_, scaleEnd_, actualTime, durationTime); + } + float scale = static_cast(scaleCur_) / SCALE_CONVERTION; + Scale(Vector2(scale, scale), pivot_); + + if (rotateStart_ != rotateEnd_) { + rotateCur_ = easingFunc_(rotateStart_, rotateEnd_, actualTime, durationTime); + } + Rotate(rotateCur_, pivot_); + } +} +} \ No newline at end of file diff --git a/frameworks/components/ui_time_picker.cpp b/frameworks/components/ui_time_picker.cpp new file mode 100755 index 0000000..a7542ba --- /dev/null +++ b/frameworks/components/ui_time_picker.cpp @@ -0,0 +1,291 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "components/ui_time_picker.h" +#include +#include +#include "securec.h" +#include "draw/draw_rect.h" +#include "graphic_log.h" +#include "themes/theme_manager.h" + +namespace OHOS { +UITimePicker::UITimePicker() + : selectedValue_{0}, + selectedHour_{0}, + selectedMinute_{0}, + selectedSecond_{0}, + secVisible_(false), + setSelectedTime_(nullptr), + pickerWidth_(0), + itemsHeight_(0), + xPos_(0), + backgroundFontSize_(0), + highlightFontSize_(0), + backgroundFontName_(nullptr), + highlightFontName_(nullptr), + pickerListener_(this), + timePickerListener_(nullptr) +{ + Theme* theme = ThemeManager::GetInstance().GetCurrent(); + if (theme != nullptr) { + style_ = &(theme->GetPickerBackgroundStyle()); + } else { + style_ = &(StyleDefault::GetPickerBackgroundStyle()); + } + backgroundFontId_ = style_->font_; + backgroundColor_ = style_->textColor_; + if (theme != nullptr) { + style_ = &(theme->GetPickerHighlightStyle()); + } else { + style_ = &(StyleDefault::GetPickerHighlightStyle()); + } + highlightFontId_ = style_->font_; + highlightColor_ = style_->textColor_; + + hourPicker_ = nullptr; + minutePicker_ = nullptr; + secondPicker_ = nullptr; +} + +UITimePicker::~UITimePicker() +{ + DeInitTimePicker(); + if (backgroundFontName_ != nullptr) { + UIFree(backgroundFontName_); + backgroundFontName_ = nullptr; + } + + if (highlightFontName_ != nullptr) { + UIFree(highlightFontName_); + highlightFontName_ = nullptr; + } +} + +void UITimePicker::InitTimePicker() +{ + xPos_ = 0; + if (secVisible_) { + pickerWidth_ = GetWidth() / SEC_VISIBLE_COUNT; + InitPicker(hourPicker_, TIME_START, HOUR_END); + xPos_ = pickerWidth_; + InitPicker(minutePicker_, TIME_START, MIN_END); + xPos_ *= (SEC_VISIBLE_COUNT - 1); + InitPicker(secondPicker_, TIME_START, SEC_END); + } else { + pickerWidth_ = GetWidth() / SEC_INVISIBLE_COUNT; + InitPicker(hourPicker_, TIME_START, HOUR_END); + xPos_ = pickerWidth_; + InitPicker(minutePicker_, TIME_START, MIN_END); + } + + if (setSelectedTime_ == nullptr) { + const char* curTime = secVisible_ ? "00:00:00" : "00:00"; + RefreshSelected(curTime); + } else { + RefreshSelected(setSelectedTime_); + } +} + +void UITimePicker::DeInitTimePicker() +{ + DeInitPicker(secondPicker_); + DeInitPicker(minutePicker_); + DeInitPicker(hourPicker_); +} + +void UITimePicker::RefreshTimePicker() +{ + DeInitTimePicker(); + InitTimePicker(); +} + +void UITimePicker::InitPicker(UIPicker*& picker, int16_t start, int16_t end) +{ + picker = new UIPicker(); + if (picker == nullptr) { + GRAPHIC_LOGE("new UIPicker fail"); + return; + } + picker->SetPosition(xPos_, 0, pickerWidth_, GetHeight()); + picker->SetItemHeight(itemsHeight_); + picker->SetFontId(backgroundFontId_, highlightFontId_); + if ((backgroundFontName_ == nullptr) || (highlightFontName_ == nullptr)) { + picker->SetFontId(backgroundFontId_, highlightFontId_); + } else { + picker->SetBackgroundFont(backgroundFontName_, backgroundFontSize_); + picker->SetHighlightFont(highlightFontName_, highlightFontSize_); + } + picker->SetTextColor(backgroundColor_, highlightColor_); + picker->SetValues(start, end); + picker->RegisterSelectedListener(&pickerListener_); + picker->SetIntercept(false); + Add(picker); + +#if ENABLE_ROTATE_INPUT + if (end == HOUR_END) { + picker->GetChildrenHead()->SetViewId(HOUR_LIST_NAME); + return; + } else if (end == MIN_END) { + if (minutePicker_->GetChildById(MIN_LIST_NAME) == nullptr) { + picker->GetChildrenHead()->SetViewId(MIN_LIST_NAME); + return; + } + } + picker->GetChildrenHead()->SetViewId(SEC_LIST_NAME); + return; +#endif +} + +void UITimePicker::DeInitPicker(UIPicker*& picker) +{ + if (picker != nullptr) { + Remove(picker); + picker->ClearValues(); + delete picker; + picker = nullptr; + } +} + +void UITimePicker::TimeSelectedCallback() +{ + uint16_t hourSelect = hourPicker_->GetSelected(); + uint16_t minSelect = minutePicker_->GetSelected(); + GetValueByIndex(selectedHour_, BUF_SIZE, hourSelect, TIME_START, HOUR_END); + GetValueByIndex(selectedMinute_, BUF_SIZE, minSelect, TIME_START, MIN_END); + + if (secVisible_) { + uint16_t secSelect = secondPicker_->GetSelected(); + GetValueByIndex(selectedSecond_, BUF_SIZE, secSelect, TIME_START, SEC_END); + if (sprintf_s(selectedValue_, SELECTED_VALUE_SIZE, "%s:%s:%s", + selectedHour_, selectedMinute_, selectedSecond_) < 0) { + return; + } + } else { + if (sprintf_s(selectedValue_, SELECTED_VALUE_SIZE, "%s:%s", selectedHour_, selectedMinute_) < 0) { + return; + } + } + + if (timePickerListener_ != nullptr) { + timePickerListener_->OnTimePickerStoped(*this); + } +} + +void UITimePicker::GetValueByIndex(char* value, uint8_t len, uint16_t index, int16_t start, int16_t end) +{ + if ((value != nullptr) && (index < end - start + 1)) { + if (sprintf_s(value, len, "%02d", index) < 0) { + return; + } + } +} + +bool UITimePicker::SetSelected(const char* value) +{ + setSelectedTime_ = value; + return RefreshSelected(value); +} + +bool UITimePicker::RefreshSelected(const char* value) +{ + uint32_t hourSelect; + uint32_t minSelect; + + if (value == nullptr) { + return false; + } + + if (secVisible_) { + uint32_t secSelect; + // 3: three variables + if (sscanf_s(value, "%d:%d:%d", &hourSelect, &minSelect, &secSelect) < 3) { + return false; + } + secondPicker_->SetSelected(secSelect); + } else { + if (sscanf_s(value, "%d:%d", &hourSelect, &minSelect) < 2) { // 2: two variables + return false; + } + } + + hourPicker_->SetSelected(hourSelect); + minutePicker_->SetSelected(minSelect); + return true; +} + +void UITimePicker::SetItemHeight(int16_t height) +{ + itemsHeight_ = height; + RefreshTimePicker(); +} + +void UITimePicker::EnableSecond(bool state) +{ + secVisible_ = state; + RefreshTimePicker(); +} + +void UITimePicker::SetTextStyle(uint8_t backgroundFontId, uint8_t highlightFontId, + ColorType backgroundColor, ColorType highlightColor) +{ + highlightFontId_ = highlightFontId; + if (highlightFontName_ != nullptr) { + UIFree(highlightFontName_); + highlightFontName_ = nullptr; + } + + backgroundFontId_ = backgroundFontId; + if (backgroundFontName_ != nullptr) { + UIFree(backgroundFontName_); + backgroundFontName_ = nullptr; + } + + highlightColor_ = highlightColor; + backgroundColor_ = backgroundColor; + RefreshTimePicker(); +} + +void UITimePicker::SetTextColor(ColorType backgroundColor, ColorType highlightColor) +{ + backgroundColor_ = backgroundColor; + highlightColor_ = highlightColor; + RefreshTimePicker(); +} + +void UITimePicker::SetBackgroundFont(const char* name, uint8_t size) +{ + Text::SetFont(name, size, backgroundFontName_, backgroundFontSize_); + RefreshTimePicker(); +} + +void UITimePicker::SetHighlightFont(const char* name, uint8_t size) +{ + Text::SetFont(name, size, highlightFontName_, highlightFontSize_); + RefreshTimePicker(); +} + +void UITimePicker::SetWidth(int16_t width) +{ + UIView::SetWidth(width); + RefreshTimePicker(); +} + +void UITimePicker::SetHeight(int16_t height) +{ + UIView::SetHeight(height); + RefreshTimePicker(); +} +} diff --git a/frameworks/components/ui_toggle_button.cpp b/frameworks/components/ui_toggle_button.cpp new file mode 100755 index 0000000..ae0b029 --- /dev/null +++ b/frameworks/components/ui_toggle_button.cpp @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "components/ui_toggle_button.h" +#include "common/image.h" +#include "draw/draw_arc.h" +#include "draw/draw_rect.h" +#include "imgdecode/cache_manager.h" + +namespace OHOS { +UIToggleButton::UIToggleButton() : width_(DEFAULT_HOT_WIDTH), height_(DEFAULT_HOT_WIDTH), + corner_(DEFAULT_CORNER_RADIUS), radius_(DEFAULT_CORNER_RADIUS - DEAFULT_RADIUS_DIFF), + rectWidth_(DEFAULT_WIDTH) +{ + image_[UNSELECTED].SetSrc(""); + image_[SELECTED].SetSrc(""); + Resize(width_, height_); +} + +void UIToggleButton::SetState(bool state) +{ + if (state) { + UICheckBox::SetState(SELECTED); + } else { + UICheckBox::SetState(UNSELECTED); + } + Invalidate(); +} + +void UIToggleButton::CalculateSize() +{ + int16_t width = GetWidth(); + int16_t height = GetHeight(); + if ((width_ == width) && (height_ == height)) { + return; + } + width_ = width; + height_ = height; + int16_t minValue = (width_ > height_) ? height_ : width_; + corner_ = DEFAULT_CORNER_RADIUS * minValue / DEFAULT_HOT_HEIGHT; + int16_t radiusDiff = DEAFULT_RADIUS_DIFF * minValue / DEFAULT_HOT_WIDTH; + radius_ = corner_ - radiusDiff; + rectWidth_ = DEFAULT_WIDTH * minValue / DEFAULT_HOT_WIDTH; +} + +void UIToggleButton::OnDraw(const Rect& invalidatedArea) +{ + if ((image_[SELECTED].GetSrcType() != IMG_SRC_UNKNOWN) && (image_[UNSELECTED].GetSrcType() != IMG_SRC_UNKNOWN)) { + UICheckBox::OnDraw(invalidatedArea); + } else { + CalculateSize(); + DrawRect::Draw(GetRect(), invalidatedArea, *style_, opaScale_); + Rect contentRect = GetContentRect(); + int16_t dx = (width_ - rectWidth_) >> 1; + int16_t dy = (height_ >> 1) - corner_; + int16_t x = contentRect.GetX() + dx; + int16_t y = contentRect.GetY() + dy; + Rect rectMid; + rectMid.SetRect(x, y, x + rectWidth_, y + (corner_ << 1) + 1); + Rect trunc = invalidatedArea; + bool isIntersect = trunc.Intersect(trunc, contentRect); + switch (state_) { + case SELECTED: { + Style styleSelect = StyleDefault::GetBackgroundTransparentStyle(); + styleSelect.borderRadius_ = corner_; + styleSelect.bgColor_ = Color::GetColorFromRGB(DEFAULT_BG_RED, DEFAULT_BG_GREEN, DEFAULT_BG_BLUE); + styleSelect.bgOpa_ = OPA_OPAQUE; + if (isIntersect) { + DrawRect::Draw(rectMid, trunc, styleSelect, opaScale_); + } + ArcInfo arcInfoRight = { + { static_cast(x + rectWidth_ - corner_), static_cast(y + corner_) }, { 0 }, + radius_, 0, CIRCLE_IN_DEGREE, nullptr + }; + styleSelect.bgColor_ = Color::White(); + styleSelect.lineWidth_ = radius_; + styleSelect.lineColor_ = Color::White(); + if (isIntersect) { + DrawArc::GetInstance()->Draw(arcInfoRight, trunc, styleSelect, OPA_OPAQUE, CapType::CAP_NONE); + } + break; + } + case UNSELECTED: { + Style styleUnSelect = StyleDefault::GetBackgroundTransparentStyle(); + styleUnSelect.bgColor_ = Color::White(); + styleUnSelect.bgOpa_ = DEFAULT_UNSELECTED_OPA; + styleUnSelect.borderRadius_ = corner_; + if (isIntersect) { + DrawRect::Draw(rectMid, trunc, styleUnSelect, opaScale_); + } + ArcInfo arcInfoLeft = { + { static_cast(x + corner_), static_cast(y + corner_) }, { 0 }, radius_, 0, + CIRCLE_IN_DEGREE, nullptr + }; + styleUnSelect.lineColor_ = Color::White(); + styleUnSelect.lineWidth_ = radius_; + if (isIntersect) { + DrawArc::GetInstance()->Draw(arcInfoLeft, trunc, styleUnSelect, OPA_OPAQUE, CapType::CAP_NONE); + } + break; + } + default: + break; + } + } +} +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/components/ui_video.cpp b/frameworks/components/ui_video.cpp new file mode 100755 index 0000000..bbf8549 --- /dev/null +++ b/frameworks/components/ui_video.cpp @@ -0,0 +1,719 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "components/ui_video.h" +#include "securec.h" + +#ifndef VERSION_LITE +namespace OHOS { +UIVideo::UIVideo() +{ + SetTouchable(true); + SetOnTouchListener(this); +} + +UIVideo::~UIVideo() +{ + if (videoPlayer_ != nullptr) { + videoPlayer_->Stop(); + videoPlayer_->Reset(); + videoPlayer_->Release(); + } + if (sliderAnimator_ != nullptr) { + AnimatorManager::GetInstance()->Remove(sliderAnimator_); + delete sliderAnimator_; + sliderAnimator_ = nullptr; + } + if (surfaceView_ != nullptr) { + delete surfaceView_; + surfaceView_ = nullptr; + } + DeleteController(); +} + +bool UIVideo::SetSrc(const char* source) +{ + if (source == nullptr) { + return false; + } + + InitVideo(); + src_ = source; + std::string uri(source); + std::map header; + Source videoSource(uri, header); + if (videoPlayer_ != nullptr) { + int32_t ret = videoPlayer_->SetSource(videoSource); + if (ret == 0) { + return true; + } + } + return false; +} + +bool UIVideo::Prepare() +{ + if (src_ == nullptr) { + return false; + } + if (videoPlayer_ == nullptr) { + return false; + } + + int32_t ret = videoPlayer_->Prepare(); + if (ret != 0) { + return false; + } + SetVolume(DEFAULT_VOLUME, DEFAULT_VOLUME); + videoPlayer_->GetDuration(duration_); + if (totalTimeLabel_ != nullptr) { + char timer[10] = {0}; // 10:timer length + if (!GetTimerFromMSecond(duration_, timer, sizeof(timer))) { + return false; + } + totalTimeLabel_->SetText(&timer[0]); + } + + if (titleLabel_ != nullptr) { + const char* fileName = nullptr; + fileName = strrchr(src_, '/'); + if (fileName != nullptr) { + titleLabel_->SetText(fileName + 1); + } + } + if (sliderAnimatorCallback_) { + sliderAnimatorCallback_->SetDuration(duration_); + } + SetSurfaceInfo(); + + playerListener_ = std::make_shared(); + playerListener_->SetVideoPlayer(this); + videoPlayer_->SetPlayerCallback(playerListener_); + return true; +} + +bool UIVideo::Play() +{ + if (videoPlayer_ != nullptr) { + int32_t ret = videoPlayer_->Play(); + if (ret == 0) { + if (sliderAnimator_ != nullptr) { + sliderAnimator_->Start(); + } + if (pauseButton_ != nullptr) { + pauseButton_->SetVisible(false); + } + if (playButton_ != nullptr) { + playButton_->SetState(true); + } + if (surfaceView_ != nullptr) { + surfaceView_->SetVisible(true); + } + if (videoPlayerListener_ != nullptr) { + videoPlayerListener_->OnPlaybackPlay(); + } + return true; + } + } + return false; +} + +bool UIVideo::IsPlaying() +{ + if (videoPlayer_ != nullptr) { + return videoPlayer_->IsPlaying(); + } + return false; +} + +bool UIVideo::Pause() +{ + if (videoPlayer_ != nullptr) { + int32_t ret = videoPlayer_->Pause(); + if (ret == 0) { + if (sliderAnimator_ != nullptr) { + sliderAnimator_->Pause(); + } + if (playButton_ != nullptr) { + playButton_->SetState(false); + } + if (pauseButton_ != nullptr) { + pauseButton_->SetVisible(true); + } + if (videoPlayerListener_ != nullptr) { + videoPlayerListener_->OnPlaybackPause(); + } + return true; + } + } + return false; +} + +bool UIVideo::Stop() +{ + if (videoPlayer_ != nullptr) { + int32_t ret = videoPlayer_->Stop(); + if (ret == 0) { + if (sliderAnimator_ != nullptr) { + sliderAnimator_->Stop(); + } + if (playSlider_ != nullptr) { + playSlider_->SetValue(0); + } + if (currentTimeLabel_ != nullptr) { + currentTimeLabel_->SetText("00:00:00"); + } + if (totalTimeLabel_ != nullptr) { + totalTimeLabel_->SetText("00:00:00"); + } + if (playButton_ != nullptr) { + playButton_->SetState(false); + } + if (pauseButton_ != nullptr) { + pauseButton_->SetVisible(true); + } + if (surfaceView_ != nullptr) { + surfaceView_->SetVisible(false); + } + if (videoPlayerListener_ != nullptr) { + videoPlayerListener_->OnPlaybackStop(); + } + return true; + } + } + return false; +} + +bool UIVideo::Rewind(int64_t mSeconds) +{ + if (videoPlayer_ != nullptr) { + int32_t ret = videoPlayer_->Rewind(mSeconds, PLAYER_SEEK_PREVIOUS_SYNC); + if (ret == 0) { + return true; + } + } + return false; +} + +bool UIVideo::SetVolume(float leftVolume, float rightVolume) +{ + if (videoPlayer_ != nullptr) { + int32_t ret = videoPlayer_->SetVolume(leftVolume * MAX_VOLUME, rightVolume * MAX_VOLUME); + if (ret == 0) { + leftVolumeValue_ = leftVolume; + rightVolumeValue_ = rightVolume; + if (volumeButton_ != nullptr) { + if ((leftVolumeValue_ == 0) && (rightVolumeValue_ == 0)) { + volumeButton_->SetState(true); + } else { + volumeButton_->SetState(false); + } + } + return true; + } + } + return false; +} + +bool UIVideo::IsSingleLooping() +{ + if (videoPlayer_ != nullptr) { + return videoPlayer_->IsSingleLooping(); + } + return false; +} + +bool UIVideo::GetCurrentTime(int64_t& time) +{ + if (videoPlayer_ != nullptr) { + int32_t ret = videoPlayer_->GetCurrentTime(time); + if (ret == 0) { + return true; + } + } + return false; +} + +bool UIVideo::GetDuration(int64_t& durationMs) +{ + if (videoPlayer_ != nullptr) { + int32_t ret = videoPlayer_->GetDuration(durationMs); + if (ret == 0) { + return true; + } + } + return false; +} + +void UIVideo::SetVideoPlayerListener(VideoPlayerListener* listener) +{ + videoPlayerListener_ = listener; + + if (playerListener_ != nullptr) { + playerListener_->SetVideoPlayerListerner(videoPlayerListener_); + } +} + +bool UIVideo::Reset() +{ + if (videoPlayer_ != nullptr) { + if (sliderAnimator_ != nullptr) { + sliderAnimator_->Stop(); + } + if (playSlider_ != nullptr) { + playSlider_->SetValue(0); + } + if (currentTimeLabel_ != nullptr) { + currentTimeLabel_->SetText("00:00"); + } + if (totalTimeLabel_ != nullptr) { + totalTimeLabel_->SetText("00:00"); + } + if (pauseButton_ != nullptr) { + pauseButton_->SetVisible(true); + } + if (playButton_ != nullptr) { + playButton_->SetState(false); + } + int32_t ret = videoPlayer_->Reset(); + if (ret == 0) { + videoPlayer_->Release(); + return true; + } + } + return false; +} + +bool UIVideo::EnableSingleLooping(bool loop) +{ + if (videoPlayer_ != nullptr) { + int32_t ret = videoPlayer_->EnableSingleLooping(loop); + if (ret == 0) { + return true; + } + } + return false; +} + +void UIVideo::ShowController(bool show) +{ + if (controllerGroup_ != nullptr) { + if (controllerGroup_->IsVisible() != show) { + controllerGroup_->SetVisible(show); + Invalidate(); + } + } +} + +void UIVideo::InitVideo() +{ + if (videoPlayer_ == nullptr) { + videoPlayer_ = std::make_shared(); + } + + InitControllerLabel(); + InitControllerButton(); + InitControllerSlider(); + + if (surfaceView_ == nullptr) { + surfaceView_ = new UISurfaceView(); + if (surfaceView_ == nullptr) { + GRAPHIC_LOGE("new UISurfaceView fail"); + return; + } + surfaceView_->SetPosition(0, 0); + surfaceView_->SetWidth(DEFAULT_VIEW_WIDTH); + surfaceView_->SetHeight(DEFAULT_VIEW_HEIGHT); + Add(surfaceView_); + } + if (controllerGroup_ == nullptr) { + controllerGroup_ = new UIViewGroup(); + if (controllerGroup_ == nullptr) { + GRAPHIC_LOGE("new UIViewGroup fail"); + return; + } + controllerGroup_->SetPosition(0, 0, DEFAULT_VIEW_WIDTH, DEFAULT_VIEW_HEIGHT); + controllerGroup_->SetStyle(STYLE_BACKGROUND_OPA, 0); + controllerGroup_->Add(titleLabel_); + controllerGroup_->Add(totalTimeLabel_); + controllerGroup_->Add(currentTimeLabel_); + controllerGroup_->Add(playSlider_); + controllerGroup_->Add(volumeButton_); + controllerGroup_->Add(playButton_); + controllerGroup_->Add(pauseButton_); + Add(controllerGroup_); + } + if (sliderAnimatorCallback_ == nullptr) { + sliderAnimatorCallback_ = new SliderAnimatorCallback(this, playSlider_, currentTimeLabel_); + if (sliderAnimatorCallback_ == nullptr) { + GRAPHIC_LOGE("new SliderAnimatorCallback fail"); + return; + } + sliderAnimatorCallback_->SetPlayButton(playButton_); + } + if (sliderAnimator_ == nullptr) { + sliderAnimator_ = new Animator(sliderAnimatorCallback_, this, 0, true); + if (sliderAnimator_ == nullptr) { + GRAPHIC_LOGE("new Animator fail"); + return; + } + AnimatorManager::GetInstance()->Add(sliderAnimator_); + sliderAnimatorCallback_->SetSliderAnimator(sliderAnimator_); + } +} + +void UIVideo::InitControllerLabel() +{ + if (titleLabel_ == nullptr) { + titleLabel_ = new UILabel(); + if (titleLabel_ == nullptr) { + GRAPHIC_LOGE("new UILabel fail"); + return; + } + titleLabel_->SetPosition(322, 28, 316, 29); // 322:pos x, 28:pos y, 316:width, 29:height + titleLabel_->SetAlign(UITextLanguageAlignment::TEXT_ALIGNMENT_CENTER, + UITextLanguageAlignment::TEXT_ALIGNMENT_CENTER); + titleLabel_->SetFont(DEFAULT_VECTOR_FONT_FILENAME, 20); // 20:font size + titleLabel_->SetText("title title"); + titleLabel_->SetTextColor(Color::White()); + } + + if (totalTimeLabel_ == nullptr) { + totalTimeLabel_ = new UILabel(); + if (totalTimeLabel_ == nullptr) { + GRAPHIC_LOGE("new UILabel fail"); + return; + } + // 580:pos x, 56:pos y offset + totalTimeLabel_->SetPosition(580, DEFAULT_VIEW_HEIGHT - 56, TIME_LABEL_WIDTH, TIME_LABEL_HEIGHT); + totalTimeLabel_->SetAlign(UITextLanguageAlignment::TEXT_ALIGNMENT_RIGHT, + UITextLanguageAlignment::TEXT_ALIGNMENT_CENTER); + totalTimeLabel_->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); + totalTimeLabel_->SetTextColor(Color::White()); + totalTimeLabel_->SetText("00:00:00"); + } + + if (currentTimeLabel_ == nullptr) { + currentTimeLabel_ = new UILabel(); + if (currentTimeLabel_ == nullptr) { + GRAPHIC_LOGE("new UILabel fail"); + return; + } + // 80:pos x, 56:pos y offset + currentTimeLabel_->SetPosition(80, DEFAULT_VIEW_HEIGHT - 56, TIME_LABEL_WIDTH, TIME_LABEL_HEIGHT); + currentTimeLabel_->SetAlign(UITextLanguageAlignment::TEXT_ALIGNMENT_LEFT, + UITextLanguageAlignment::TEXT_ALIGNMENT_CENTER); + currentTimeLabel_->SetStyle(STYLE_BACKGROUND_COLOR, Color::Red().full); + currentTimeLabel_->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); + currentTimeLabel_->SetText("00:00:00"); + currentTimeLabel_->SetTextColor(Color::White()); + } +} + +void UIVideo::InitControllerButton() +{ + if (playButton_ == nullptr) { + playButton_ = new UIToggleButton(); + if (playButton_ == nullptr) { + GRAPHIC_LOGE("new UIToggleButton fail"); + return; + } + // 24:pox x, 88:pos y offset + playButton_->SetPosition(24, DEFAULT_VIEW_HEIGHT - 88, TOGGLE_BUTTON_WIDTH, TOGGLE_BUTTON_HEIGHT); + playButton_->SetImages(MEDIA_IMAGE_PAUSE, MEDIA_IMAGE_PLAY); + playButton_->SetState(true); + playButton_->SetOnClickListener(this); + } + + if (pauseButton_ == nullptr) { + pauseButton_ = new UIToggleButton(); + if (pauseButton_ == nullptr) { + GRAPHIC_LOGE("new UIToggleButton fail"); + return; + } + // 448:pox x, 208:pos y 2:double width 2:double height + pauseButton_->SetPosition(448, 208, 2 * TOGGLE_BUTTON_WIDTH, 2 * TOGGLE_BUTTON_HEIGHT); + pauseButton_->SetImages(MEDIA_IMAGE_PLAY_CENTER, MEDIA_IMAGE_PLAY_CENTER); + pauseButton_->SetVisible(false); + pauseButton_->SetOnClickListener(this); + } + + if (volumeButton_ == nullptr) { + volumeButton_ = new UIToggleButton(); + if (volumeButton_ == nullptr) { + GRAPHIC_LOGE("new UIToggleButton fail"); + return; + } + // 56:pox x offset, 88:pos y offset + volumeButton_->SetPosition(DEFAULT_VIEW_WIDTH - 56, DEFAULT_VIEW_HEIGHT - 88, TOGGLE_BUTTON_WIDTH, + TOGGLE_BUTTON_HEIGHT); + volumeButton_->SetImages(MEDIA_IMAGE_MUTE, MEDIA_IMAGE_VOLUME); + volumeButton_->SetOnClickListener(this); + } +} + +void UIVideo::OnVideoComplete() +{ + if (videoPlayer_ != nullptr) { + videoPlayer_->Stop(); + completeFlag_ = true; + + if (sliderAnimator_ != nullptr) { + sliderAnimator_->Stop(); + } + if (playSlider_ != nullptr) { + playSlider_->SetValue(playSlider_->GetRangeMax()); + } + if (playButton_ != nullptr) { + playButton_->SetState(false); + } + if (pauseButton_ != nullptr) { + pauseButton_->SetVisible(true); + } + if (controllerGroup_ != nullptr) { + controllerGroup_->SetVisible(true); + } + Invalidate(); + } +} + +void UIVideo::InitControllerSlider() +{ + if (playSlider_ == nullptr) { + playSlider_ = new UISlider(); + if (playSlider_ == nullptr) { + GRAPHIC_LOGE("new UISlider fail"); + return; + } + // 80:pos x, 74:width offset, 5:multiply, 6:divide, 4:height + playSlider_->SetPosition(80, DEFAULT_VIEW_HEIGHT - 74, DEFAULT_VIEW_WIDTH * 5 / 6, 4); + playSlider_->SetValidHeight(4); // 4:height + playSlider_->SetValidWidth(DEFAULT_VIEW_WIDTH * 5 / 6); // 5:multiply, 6:divide + playSlider_->SetRange(100, 0); // 100:range max + playSlider_->SetValue(0); + playSlider_->SetKnobWidth(KNOB_WIDTH); + playSlider_->SetSliderRadius(5, 5, KNOB_WIDTH / 2); // 5:background radius, 5:foreground radius, 2:half + playSlider_->SetKnobStyle(STYLE_BACKGROUND_COLOR, Color::White().full); + playSlider_->SetBackgroundStyle(STYLE_BACKGROUND_COLOR, 0x1A888888); // 0x1A888888:slider background color + playSlider_->SetBackgroundStyle(STYLE_BACKGROUND_OPA, 90); // 90:background opa + playSlider_->SetDirection(UISlider::Direction::DIR_LEFT_TO_RIGHT); + playSlider_->SetSliderEventListener(this); + } +} + +void UIVideo::DeleteController() +{ + if (controllerGroup_ != nullptr) { + controllerGroup_->RemoveAll(); + delete controllerGroup_; + controllerGroup_ = nullptr; + } + if (playButton_ != nullptr) { + delete playButton_; + playButton_ = nullptr; + } + if (pauseButton_ != nullptr) { + delete pauseButton_; + pauseButton_ = nullptr; + } + if (volumeButton_ != nullptr) { + delete volumeButton_; + volumeButton_ = nullptr; + } + if (playSlider_ != nullptr) { + delete playSlider_; + playSlider_ = nullptr; + } + if (sliderAnimatorCallback_ != nullptr) { + delete sliderAnimatorCallback_; + sliderAnimatorCallback_ = nullptr; + } + if (titleLabel_ != nullptr) { + delete titleLabel_; + titleLabel_ = nullptr; + } + if (totalTimeLabel_ != nullptr) { + delete totalTimeLabel_; + totalTimeLabel_ = nullptr; + } + if (currentTimeLabel_ != nullptr) { + delete currentTimeLabel_; + currentTimeLabel_ = nullptr; + } +} + +bool UIVideo::OnClick(UIView& view, const ClickEvent& event) +{ + if (videoPlayer_ == nullptr) { + return true; + } + if (&view == playButton_) { + if (completeFlag_) { + completeFlag_ = false; + if (pauseButton_ != nullptr) { + pauseButton_->SetVisible(true); + } + if (controllerGroup_ != nullptr) { + controllerGroup_->SetVisible(true); + } + return true; + } + + if ((sliderAnimatorCallback_ != nullptr) && (pauseButton_ != nullptr) && (playButton_ != nullptr)) { + sliderAnimatorCallback_->ResetTickTime(); + if (playButton_->GetState()) { + Play(); + pauseButton_->SetVisible(false); + } else { + Pause(); + pauseButton_->SetVisible(true); + } + pauseButton_->Invalidate(); + } + } else if (&view == pauseButton_) { + if ((pauseButton_ != nullptr) && pauseButton_->IsVisible()) { + pauseButton_->SetVisible(false); + Play(); + } + } else if (&view == volumeButton_) { + if ((volumeButton_ != nullptr) && volumeButton_->GetState()) { + videoPlayer_->SetVolume(0, 0); + } else { + SetVolume(leftVolumeValue_, rightVolumeValue_); + } + } + return true; +} + +bool UIVideo::OnPress(UIView& view, const PressEvent& event) +{ + if (sliderAnimatorCallback_ != nullptr) { + sliderAnimatorCallback_->ResetTickTime(); + if (controllerGroup_ != nullptr) { + controllerGroup_->SetVisible(true); + } + Invalidate(); + } + return true; +} + +void UIVideo::OnChange(int32_t progress) +{ + if (videoPlayer_ != nullptr) { + if (sliderAnimatorCallback_ != nullptr) { + sliderAnimatorCallback_->ResetTickTime(); + } + int64_t currentValue = progress * duration_ / 100; // 100:percent + if (currentTimeLabel_ != nullptr) { + char timer[10] = {0}; // 10:timer length + if (!GetTimerFromMSecond(currentValue, timer, sizeof(timer))) { + return; + } + currentTimeLabel_->SetText(&timer[0]); + } + videoPlayer_->Rewind(currentValue, PLAYER_SEEK_PREVIOUS_SYNC); + } +} + +void UIVideo::SetSurfaceInfo() +{ + if (videoPlayer_ == nullptr) { + return; + } + int32_t width = 0; + int32_t height = 0; + videoPlayer_->GetVideoWidth(width); + videoPlayer_->GetVideoHeight(height); + + if ((width <= 0) || (height <= 0)) { + videoPlayer_->Reset(); + return; + } + + int16_t viewWidth = GetWidth(); + int16_t viewHeight = GetHeight(); + if ((viewWidth <= 0) || (viewHeight <= 0)) { + videoPlayer_->Reset(); + return; + } + float ratioX = static_cast(width) / viewWidth; + float ratioY = static_cast(height) / viewHeight; + uint16_t surfaceViewWidth; + uint16_t surfaceViewHeight; + uint16_t surfaceViewPositionX = 0; + uint16_t surfaceViewPositionY = 0; + if (ratioX > ratioY) { + surfaceViewWidth = viewWidth; + surfaceViewHeight = height / ratioX; + surfaceViewPositionY = (viewHeight - surfaceViewHeight) / 2; // 2:half + } else { + surfaceViewWidth = width / ratioY; + surfaceViewHeight = viewHeight; + surfaceViewPositionX = (viewWidth - surfaceViewWidth) / 2; // 2:half + } + if (surfaceView_ != nullptr) { + surfaceView_->SetPosition(surfaceViewPositionX, surfaceViewPositionY); + surfaceView_->SetWidth(surfaceViewWidth - 1); + surfaceView_->SetHeight(surfaceViewHeight); + videoPlayer_->SetVideoSurface(surfaceView_->GetSurface()); + } +} + +bool UIVideo::GetTimerFromMSecond(int64_t currentTime, char* timer, int32_t len) +{ + int64_t currentSecond = currentTime / 1000; // 1000:millisecond + int32_t second = currentSecond % 60; // 60:second + int32_t minute = (currentSecond / 60) % 60; // 60:minute 60:second + int32_t hour = (currentSecond / 60) / 60; // 60:minute 60:second + int32_t ret = 0; + ret = sprintf_s(timer, len, "%02d:%02d:%02d", hour, minute, second); + if (ret < 0) { + return false; + } + return true; +} + +void UIVideo::SliderAnimatorCallback::Callback(UIView* view) +{ + if (video_ != nullptr) { + int64_t currentTime = 0; + video_->GetCurrentTime(currentTime); + if (timeLabel_ != nullptr) { + char timer[10] = {0}; // 10:timer length + if (!video_->GetTimerFromMSecond(currentTime, timer, sizeof(timer))) { + return; + } + timeLabel_->SetText(&timer[0]); + timeLabel_->Invalidate(); + } + if (slider_ != nullptr) { + int64_t curPosition = currentTime * slider_->GetRangeMax() / duration_; + slider_->SetValue(curPosition); + slider_->Invalidate(); + } + + uint32_t runTime = 0; + if (sliderAnimator_ != nullptr) { + runTime = sliderAnimator_->GetRunTime(); + } + if ((runTime > tickCount_) && (runTime - tickCount_ >= HIDE_MILLI_SECOND)) { + video_->ShowController(false); + tickCount_ = runTime; + } + } +} +} // namespace OHOS + +#endif // VERSION_LITE \ No newline at end of file diff --git a/frameworks/components/ui_view.cpp b/frameworks/components/ui_view.cpp new file mode 100755 index 0000000..5838a4b --- /dev/null +++ b/frameworks/components/ui_view.cpp @@ -0,0 +1,785 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "components/ui_view.h" +#include "components/root_view.h" +#include "core/render_manager.h" +#include "dock/focus_manager.h" +#include "draw/draw_rect.h" +#include "graphic_log.h" +#include "themes/theme_manager.h" + +namespace OHOS { +UIView::UIView() + : touchable_(false), + visible_(true), + draggable_(false), + dragParentInstead_(true), + isViewGroup_(false), + needRedraw_(false), + styleAllocFlag_(false), + isIntercept_(true), + opaScale_(OPA_OPAQUE), + index_(0), + id_(nullptr), + parent_(nullptr), + nextSibling_(nullptr), + style_(nullptr), + transMap_(nullptr), + onClickListener_(nullptr), + onLongPressListener_(nullptr), + onDragListener_(nullptr), + onTouchListener_(nullptr), +#if ENABLE_ROTATE_INPUT + onRotateListener_(nullptr), +#endif + viewExtraMsg_(nullptr), + rect_(0, 0, 0, 0), + visibleRect_(nullptr) +{ + SetupThemeStyles(); +} + +UIView::~UIView() +{ + if (transMap_ != nullptr) { + delete transMap_; + transMap_ = nullptr; + } + if (visibleRect_ != nullptr) { + delete visibleRect_; + visibleRect_ = nullptr; + } + if (styleAllocFlag_) { + delete style_; + style_ = nullptr; + styleAllocFlag_ = false; + } +} + +bool UIView::OnPreDraw(Rect& invalidatedArea) const +{ + Rect rect(GetRect()); + int16_t r = style_->borderRadius_; + if (r == COORD_MAX) { + return true; + } + if (r != 0) { + r = ((r & 0x1) == 0) ? (r >> 1) : ((r + 1) >> 1); + rect.SetLeft(rect.GetX() + r); + rect.SetWidth(rect.GetWidth() - r); + rect.SetTop(rect.GetY() + r); + rect.SetHeight(rect.GetHeight() - r); + } + if (rect.IsContains(invalidatedArea)) { + return true; + } + invalidatedArea.Intersect(invalidatedArea, rect); + return false; +} + +void UIView::OnDraw(const Rect& invalidatedArea) +{ + uint8_t opa = GetMixOpaScale(); + DrawRect::Draw(GetOrigRect(), invalidatedArea, *style_, opa); +} + +void UIView::SetupThemeStyles() +{ + Theme* theme = ThemeManager::GetInstance().GetCurrent(); + if (theme != nullptr) { + style_ = &(theme->GetMainStyle()); + } else { + style_ = &(StyleDefault::GetDefaultStyle()); + } +} + +void UIView::SetStyle(Style& style) +{ + if (styleAllocFlag_) { + delete style_; + styleAllocFlag_ = false; + } + style_ = &style; +} + +void UIView::SetStyle(uint8_t key, int64_t value) +{ + if (!styleAllocFlag_) { + style_ = new Style(*style_); + if (style_ == nullptr) { + GRAPHIC_LOGE("new Style fail"); + return; + } + styleAllocFlag_ = true; + } + int16_t width = GetWidth(); + int16_t height = GetHeight(); + style_->SetStyle(key, value); + switch (key) { + case STYLE_BORDER_WIDTH: { + SetWidth(width); + SetHeight(height); + break; + } + case STYLE_PADDING_LEFT: + case STYLE_PADDING_RIGHT: { + SetWidth(width); + break; + } + case STYLE_PADDING_TOP: + case STYLE_PADDING_BOTTOM: { + SetHeight(height); + break; + } + default: + break; + } +} + +void UIView::Rotate(int16_t angle, const Vector2& pivot) +{ + if (transMap_ == nullptr) { + ReMeasure(); + transMap_ = new TransformMap(); + if (transMap_ == nullptr) { + GRAPHIC_LOGE("new TransformMap fail"); + return; + } + } + Rect joinRect = transMap_->GetBoxRect(); + transMap_->SetTransMapRect(GetOrigRect()); + transMap_->Rotate(angle, pivot); + joinRect.Join(joinRect, transMap_->GetBoxRect()); + joinRect.Join(joinRect, GetOrigRect()); + InvalidateRect(joinRect); +} + +void UIView::Scale(const Vector2& scale, const Vector2& pivot) +{ + if (transMap_ == nullptr) { + ReMeasure(); + transMap_ = new TransformMap(); + if (transMap_ == nullptr) { + GRAPHIC_LOGE("new TransformMap fail"); + return; + } + } + Rect joinRect = transMap_->GetBoxRect(); + transMap_->SetTransMapRect(GetOrigRect()); + transMap_->Scale(scale, pivot); + joinRect.Join(joinRect, transMap_->GetBoxRect()); + joinRect.Join(joinRect, GetOrigRect()); + InvalidateRect(joinRect); +} + +void UIView::Translate(const Vector2& trans) +{ + if (transMap_ == nullptr) { + ReMeasure(); + transMap_ = new TransformMap(GetOrigRect()); + if (transMap_ == nullptr) { + GRAPHIC_LOGE("new TransformMap fail"); + return; + } + } + transMap_->Translate(trans); + + Rect prevRect = GetRect(); + Rect mapRect = transMap_->GetBoxRect(); + + Rect joinRect; + joinRect.Join(prevRect, mapRect); + InvalidateRect(joinRect); +} + +bool UIView::IsTransInvalid() +{ + if (transMap_ == nullptr) { + return true; + } + return transMap_->IsInvalid(); +} + +void UIView::ResetTransParameter() +{ + if (transMap_ != nullptr) { + delete transMap_; + transMap_ = nullptr; + } +} + +#if ENABLE_ROTATE_INPUT +void UIView::RequestFocus() +{ + FocusManager::GetInstance()->RequestFocus(this); +} + +void UIView::ClearFocus() +{ + FocusManager::GetInstance()->ClearFocus(); +} +#endif + +void UIView::Invalidate() +{ + InvalidateRect(GetOrigRect()); +} + +void UIView::InvalidateRect(const Rect& invalidatedArea) +{ + if (!visible_) { + if (needRedraw_) { + needRedraw_ = false; + } else { + return; + } + } + + Rect trunc(invalidatedArea); + bool isIntersect = true; + UIView* par = parent_; + UIView* cur = this; + + while (par != nullptr) { + if (!par->visible_) { + return; + } + + isIntersect = trunc.Intersect(par->GetContentRect(), trunc); + if (!isIntersect) { + break; + } + + cur = par; + par = par->parent_; + } + + if (isIntersect && (cur->GetViewType() == UI_ROOT_VIEW)) { + RootView* rootView = reinterpret_cast(cur); + rootView->AddInvalidateRectWithLock(trunc, this); + } +} + +bool UIView::OnLongPressEvent(const LongPressEvent& event) +{ + if (onLongPressListener_ != nullptr) { + /* To ensure version compatibility, the listeners of both versions are invoked. */ + bool isConsumed = onLongPressListener_->OnLongPress(*this, event); + return isConsumed; + } + return false; +} + +bool UIView::OnDragStartEvent(const DragEvent& event) +{ + if (onDragListener_ != nullptr) { + /* To ensure version compatibility, the listeners of both versions are invoked. */ + bool isConsumed = onDragListener_->OnDragStart(*this, event); + return isConsumed; + } + return false; +} + +bool UIView::OnDragEvent(const DragEvent& event) +{ + if (onDragListener_ != nullptr) { + /* To ensure version compatibility, the listeners of both versions are invoked. */ + bool isConsumed = onDragListener_->OnDrag(*this, event); + return isConsumed; + } + return false; +} + +bool UIView::OnDragEndEvent(const DragEvent& event) +{ + if (onDragListener_ != nullptr) { + /* To ensure version compatibility, the listeners of both versions are invoked. */ + bool isConsumed = onDragListener_->OnDragEnd(*this, event); + return isConsumed; + } + return false; +} + +bool UIView::OnClickEvent(const ClickEvent& event) +{ + if (onClickListener_ != nullptr) { + /* To ensure version compatibility, the listeners of both versions are invoked. */ + bool isConsumed = onClickListener_->OnClick(*this, event); + return isConsumed; + } + return false; +} + +bool UIView::OnPressEvent(const PressEvent& event) +{ + if (onTouchListener_ != nullptr) { + /* To ensure version compatibility, the listeners of both versions are invoked. */ + bool isConsumed = onTouchListener_->OnPress(*this, event); + return isConsumed; + } + return false; +} + +bool UIView::OnReleaseEvent(const ReleaseEvent& event) +{ + if (onTouchListener_ != nullptr) { + /* To ensure version compatibility, the listeners of both versions are invoked. */ + bool isConsumed = onTouchListener_->OnRelease(*this, event); + return isConsumed; + } + return false; +} + +bool UIView::OnCancelEvent(const CancelEvent& event) +{ + if (onTouchListener_ != nullptr) { + /* To ensure version compatibility, the listeners of both versions are invoked. */ + bool isConsumed = onTouchListener_->OnCancel(*this, event); + return isConsumed; + } + return false; +} + +#if ENABLE_ROTATE_INPUT +bool UIView::OnRotateEvent(const RotateEvent& event) +{ + if (onRotateListener_ != nullptr) { + return onRotateListener_->OnRotate(*this, event); + } + return false; +} +#endif + +void UIView::GetTargetView(const Point& point, UIView** last) +{ + if (last == nullptr) { + return; + } + UIView* par = parent_; + Rect rect = GetRect(); + + if (par != nullptr) { + rect.Intersect(par->GetContentRect(), rect); + } + + if (visible_ && touchable_ && rect.IsContains(point)) { + *last = this; + } +} + +void UIView::GetTargetView(const Point& point, UIView** current, UIView** target) +{ + if (current == nullptr) { + return; + } + UIView* par = parent_; + Rect rect = GetRect(); + + if (par != nullptr) { + rect.Intersect(par->GetContentRect(), rect); + } + + if (visible_ && rect.IsContains(point)) { + if (touchable_) { + *current = this; + } + *target = this; + } +} + +Rect UIView::GetRect() const +{ + if ((transMap_ != nullptr) && !transMap_->IsInvalid()) { + Rect r = transMap_->GetBoxRect(); + Rect origRect = GetOrigRect(); + r.SetX(r.GetX() + origRect.GetX() - transMap_->GetTransMapRect().GetX()); + r.SetY(r.GetY() + origRect.GetY() - transMap_->GetTransMapRect().GetY()); + return r; + } + return GetOrigRect(); +} + +Rect UIView::GetContentRect() +{ + if ((transMap_ != nullptr) && !transMap_->IsInvalid()) { + Rect r = transMap_->GetBoxRect(); + Rect origRect = GetOrigRect(); + r.SetX(r.GetX() + origRect.GetX() - transMap_->GetTransMapRect().GetX()); + r.SetY(r.GetY() + origRect.GetY() - transMap_->GetTransMapRect().GetY()); + return r; + } + + Rect contentRect = GetRect(); + contentRect.SetX(contentRect.GetX() + style_->paddingLeft_ + style_->borderWidth_); + contentRect.SetY(contentRect.GetY() + style_->paddingTop_ + style_->borderWidth_); + contentRect.SetWidth(GetWidth()); + contentRect.SetHeight(GetHeight()); + return contentRect; +} + +Rect UIView::GetOrigRect() const +{ + int16_t x = rect_.GetX(); + int16_t y = rect_.GetY(); + UIView* par = parent_; + while (par != nullptr) { + x += par->GetX() + par->style_->paddingLeft_ + par->style_->borderWidth_; + y += par->GetY() + par->style_->paddingTop_ + par->style_->borderWidth_; + par = par->parent_; + } + return Rect(x, y, x + rect_.GetWidth() - 1, y + rect_.GetHeight() - 1); +} + +Rect UIView::GetMaskedRect() const +{ + Rect mask; + if (visibleRect_ != nullptr) { + mask.Intersect(GetRect(), GetVisibleRect()); + } else { + mask = GetRect(); + } + return mask; +} + +Rect UIView::GetVisibleRect() const +{ + if (visibleRect_ == nullptr) { + return GetRect(); + } + Rect absoluteRect; + int16_t x = visibleRect_->GetX(); + int16_t y = visibleRect_->GetY(); + UIView* par = parent_; + while (par != nullptr) { + x += par->GetX(); + y += par->GetY(); + par = par->parent_; + } + absoluteRect.SetX(x); + absoluteRect.SetY(y); + absoluteRect.SetWidth(visibleRect_->GetWidth()); + absoluteRect.SetHeight(visibleRect_->GetHeight()); + return absoluteRect; +} + +void UIView::SetTransformMap(const TransformMap& transMap) +{ + if (transMap.IsInvalid()) { + return; + } + + if ((transMap_ != nullptr) && (*transMap_ == transMap)) { + return; + } + + Rect prevRect = GetRect(); + Rect mapRect = transMap.GetBoxRect(); + + Rect joinRect; + joinRect.Join(prevRect, mapRect); + + InvalidateRect(joinRect); + + if (transMap_ == nullptr) { + transMap_ = new TransformMap(); + } + + *transMap_ = transMap; +} + +void UIView::SetWidthPercent(float widthPercent) +{ + if (IsInvalid(widthPercent)) { + return; + } + if ((GetParent() != nullptr) && (GetParent()->GetWidth() > 1)) { + int16_t newWidth = static_cast(GetParent()->GetWidth() * widthPercent); + SetWidth(newWidth); + } +} + +void UIView::SetHeightPercent(float heightPercent) +{ + if (IsInvalid(heightPercent)) { + return; + } + if ((GetParent() != nullptr) && (GetParent()->GetHeight() > 1)) { + int16_t newHeight = static_cast(GetParent()->GetHeight() * heightPercent); + SetHeight(newHeight); + } +} + +void UIView::ResizePercent(float widthPercent, float heightPercent) +{ + if (IsInvalid(widthPercent) || IsInvalid(heightPercent)) { + return; + } + if ((GetParent() != nullptr) && (GetParent()->GetWidth() > 1) && (GetParent()->GetHeight() > 1)) { + int16_t newWidth = static_cast(GetParent()->GetWidth() * widthPercent); + int16_t newHeight = static_cast(GetParent()->GetHeight() * heightPercent); + Resize(newWidth, newHeight); + } +} + +void UIView::SetXPercent(float xPercent) +{ + if (IsInvalid(xPercent)) { + return; + } + if ((GetParent() != nullptr) && (GetParent()->GetWidth() > 1)) { + int16_t newX = static_cast(GetParent()->GetWidth() * xPercent); + SetX(newX); + } +} + +void UIView::SetYPercent(float yPercent) +{ + if (IsInvalid(yPercent)) { + return; + } + if ((GetParent() != nullptr) && (GetParent()->GetHeight() > 1)) { + int16_t newY = static_cast(GetParent()->GetHeight() * yPercent); + SetY(newY); + } +} + +void UIView::SetPositionPercent(float xPercent, float yPercent) +{ + if (IsInvalid(xPercent) || IsInvalid(yPercent)) { + return; + } + if ((GetParent() != nullptr) && (GetParent()->GetWidth() > 1) && (GetParent()->GetHeight() > 1)) { + int16_t newX = static_cast(GetParent()->GetWidth() * xPercent); + int16_t newY = static_cast(GetParent()->GetHeight() * yPercent); + SetPosition(newX, newY); + } +} + +void UIView::SetPositionPercent(float xPercent, float yPercent, float widthPercent, float heightPercent) +{ + if (IsInvalid(xPercent) || IsInvalid(yPercent) || IsInvalid(widthPercent) || IsInvalid(heightPercent)) { + return; + } + if ((GetParent() != nullptr) && (GetParent()->GetWidth() > 1) && (GetParent()->GetHeight() > 1)) { + int16_t newX = static_cast(GetParent()->GetWidth() * xPercent); + int16_t newY = static_cast(GetParent()->GetHeight() * yPercent); + int16_t newWidth = static_cast(GetParent()->GetWidth() * widthPercent); + int16_t newHeight = static_cast(GetParent()->GetHeight() * heightPercent); + SetPosition(newX, newY, newWidth, newHeight); + } +} + +bool UIView::IsInvalid(float percent) +{ + if ((percent < 1) && (percent > 0)) { + return false; + } + return true; +} + +void UIView::LayoutCenterOfParent(int16_t xOffset, int16_t yOffset) +{ + if (parent_ == nullptr) { + return; + } + + int16_t topMargin = style_->marginTop_; + int16_t leftMargin = style_->marginLeft_; + int16_t rightMargin = style_->marginRight_; + int16_t bottomMargin = style_->marginBottom_; + // 2: half + int16_t posX = parent_->GetWidth() / 2 - (rect_.GetWidth() - leftMargin + rightMargin) / 2 + xOffset; + int16_t posY = parent_->GetHeight() / 2 - (rect_.GetHeight() - topMargin + bottomMargin) / 2 + yOffset; + SetPosition(posX, posY); +} + +void UIView::LayoutLeftOfParent(int16_t offset) +{ + if (parent_ == nullptr) { + return; + } + + int16_t leftMargin = style_->marginLeft_; + SetPosition(leftMargin + offset, GetY()); +} + +void UIView::LayoutRightOfParent(int16_t offset) +{ + if (parent_ == nullptr) { + return; + } + + int16_t rightMargin = style_->marginRight_; + SetPosition(parent_->GetWidth() - offset - rect_.GetWidth() - rightMargin, GetY()); +} + +void UIView::LayoutTopOfParent(int16_t offset) +{ + if (parent_ == nullptr) { + return; + } + + int16_t topMargin = style_->marginTop_; + SetPosition(GetX(), topMargin + offset); +} + +void UIView::LayoutBottomOfParent(int16_t offset) +{ + if (parent_ == nullptr) { + return; + } + + int16_t bottomMargin = style_->marginBottom_; + SetPosition(GetX(), parent_->GetHeight() - offset - rect_.GetHeight() - bottomMargin); +} + +void UIView::AlignLeftToSibling(const char* id, int16_t offset) +{ + if (parent_ == nullptr) { + return; + } + UIView* sib = parent_->GetChildById(id); + if (sib != nullptr) { + int16_t margin = sib->style_->marginLeft_ - style_->marginLeft_; + SetPosition(sib->GetX() - margin + offset, GetY()); + } +} + +void UIView::AlignRightToSibling(const char* id, int16_t offset) +{ + if (parent_ == nullptr) { + return; + } + UIView* sib = parent_->GetChildById(id); + if (sib != nullptr) { + int16_t margin = sib->style_->marginRight_ - style_->marginRight_; + SetPosition(sib->GetX() + sib->rect_.GetWidth() - rect_.GetWidth() - offset + margin, GetY()); + } +} + +void UIView::AlignTopToSibling(const char* id, int16_t offset) +{ + if (parent_ == nullptr) { + return; + } + UIView* sib = parent_->GetChildById(id); + if (sib != nullptr) { + int16_t margin = sib->style_->marginTop_ - style_->marginTop_; + SetPosition(GetX(), sib->GetY() + offset - margin); + } +} + +void UIView::AlignBottomToSibling(const char* id, int16_t offset) +{ + if (parent_ == nullptr) { + return; + } + UIView* sib = parent_->GetChildById(id); + if (sib != nullptr) { + int16_t margin = sib->style_->marginBottom_ - style_->marginBottom_; + SetPosition(GetX(), sib->GetY() + sib->rect_.GetHeight() - rect_.GetHeight() - offset + margin); + } +} + +void UIView::AlignHorCenterToSibling(const char* id, int16_t offset) +{ + if (parent_ == nullptr) { + return; + } + UIView* sib = parent_->GetChildById(id); + if (sib != nullptr) { + int16_t margin = + (sib->style_->marginRight_ - sib->style_->marginLeft_ - style_->marginRight_ + style_->marginLeft_) / + 2; // 2 : half + SetPosition(sib->GetX() + sib->rect_.GetWidth() / 2 - rect_.GetWidth() / 2 + margin + offset, GetY()); + } +} +void UIView::AlignVerCenterToSibling(const char* id, int16_t offset) +{ + if (parent_ == nullptr) { + return; + } + UIView* sib = parent_->GetChildById(id); + if (sib != nullptr) { + int16_t margin = + (sib->style_->marginBottom_ - sib->style_->marginTop_ - style_->marginBottom_ + style_->marginTop_) / + 2; // 2 : half + SetPosition(GetX(), sib->GetY() + sib->rect_.GetHeight() / 2 - rect_.GetHeight() / 2 + margin + offset); + } +} + +void UIView::LayoutLeftToSibling(const char* id, int16_t offset) +{ + if (parent_ == nullptr) { + return; + } + UIView* sib = parent_->GetChildById(id); + if (sib != nullptr) { + int16_t margin = sib->style_->marginLeft_ + style_->marginRight_; + SetPosition(sib->GetX() - offset - rect_.GetWidth() - margin, GetY()); + } +} + +void UIView::LayoutRightToSibling(const char* id, int16_t offset) +{ + if (parent_ == nullptr) { + return; + } + UIView* sib = parent_->GetChildById(id); + if (sib != nullptr) { + int16_t margin = sib->style_->marginRight_ + style_->marginLeft_; + SetPosition(sib->GetX() + sib->rect_.GetWidth() + offset + margin, GetY()); + } +} + +void UIView::LayoutTopToSibling(const char* id, int16_t offset) +{ + if (parent_ == nullptr) { + return; + } + UIView* sib = parent_->GetChildById(id); + if (sib != nullptr) { + int16_t margin = sib->style_->marginTop_ + style_->marginBottom_; + SetPosition(GetX(), sib->GetY() - offset - rect_.GetHeight() - margin); + } +} + +void UIView::LayoutBottomToSibling(const char* id, int16_t offset) +{ + if (parent_ == nullptr) { + return; + } + UIView* sib = parent_->GetChildById(id); + if (sib != nullptr) { + int16_t margin = sib->style_->marginBottom_ + style_->marginTop_; + SetPosition(GetX(), sib->GetY() + sib->rect_.GetHeight() + offset + margin); + } +} + +uint8_t UIView::GetMixOpaScale() +{ + uint8_t opaMix = opaScale_; + UIView* parent = parent_; + uint8_t opaParent; + while (parent != nullptr) { + opaParent = parent->GetOpaScale(); + // 8: Shift right 8 bits + opaMix = (opaParent == OPA_OPAQUE) ? opaMix : ((static_cast(opaParent) * opaMix) >> 8); + parent = parent->GetParent(); + } + return opaMix; +} +} // namespace OHOS diff --git a/frameworks/components/ui_view_group.cpp b/frameworks/components/ui_view_group.cpp new file mode 100755 index 0000000..705bf13 --- /dev/null +++ b/frameworks/components/ui_view_group.cpp @@ -0,0 +1,299 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "components/ui_view_group.h" + +#include +#include "components/root_view.h" + +namespace OHOS { +UIViewGroup::UIViewGroup() + : childrenHead_(nullptr), childrenTail_(nullptr), childrenNum_(0), + isDragging_(false), disallowIntercept_(false), isAutoSize_(false) +{ + isViewGroup_ = true; +} + +UIViewGroup::~UIViewGroup() {} + +void UIViewGroup::Add(UIView* view) +{ + if ((view == this) || (view == nullptr)) { + return; + } + if (childrenHead_ == nullptr) { + childrenHead_ = view; + } else { + UIView* head = childrenHead_; + while (head != nullptr) { + if ((view == head) || + ((view->GetViewId() != nullptr) && + (head->GetViewId() != nullptr) && + !strcmp(view->GetViewId(), head->GetViewId()))) { + return; + } + head = head->GetNextSibling(); + } + + if (childrenTail_ == nullptr) { + return; + } + childrenTail_->SetNextSibling(view); + } + view->SetParent(this); + view->SetNextSibling(nullptr); + childrenTail_ = view; + childrenNum_++; + if (isAutoSize_) { + AutoResize(); + } + OnChildChanged(); +} + +void UIViewGroup::Insert(UIView* prevView, UIView* insertView) +{ + if (insertView == nullptr) { + return; + } + if (childrenHead_ == nullptr) { + Add(insertView); + return; + } + UIView* head = childrenHead_; + while (head != nullptr) { + if ((insertView == head) || + ((insertView->GetViewId() != nullptr) && + (head->GetViewId() != nullptr) && + !strcmp(insertView->GetViewId(), head->GetViewId()))) { + return; + } + head = head->GetNextSibling(); + } + if (prevView == nullptr) { + insertView->SetNextSibling(childrenHead_); + insertView->SetParent(this); + childrenHead_ = insertView; + } else { + UIView* nextView = prevView->GetNextSibling(); + prevView->SetNextSibling(insertView); + insertView->SetNextSibling(nextView); + insertView->SetParent(this); + } + if (childrenTail_ == prevView) { + childrenTail_ = insertView; + } + childrenNum_++; + if (isAutoSize_) { + AutoResize(); + } + OnChildChanged(); +} + +void UIViewGroup::Remove(UIView* view) +{ + if ((childrenHead_ == nullptr) || (view == nullptr)) { + return; + } + +#if LOCAL_RENDER + RootView::GetInstance()->RemoveViewFromInvalidMap(view); + InvalidateRect(view->GetRect()); +#endif + if (childrenHead_ == view) { + childrenHead_ = childrenHead_->GetNextSibling(); + view->SetParent(nullptr); + view->SetNextSibling(nullptr); + if (childrenTail_ == view) { + childrenTail_ = nullptr; + } + childrenNum_--; + OnChildChanged(); + return; + } + UIView* node = childrenHead_; + while (node->GetNextSibling() != nullptr) { + if (node->GetNextSibling() == view) { + node->SetNextSibling(view->GetNextSibling()); + view->SetParent(nullptr); + view->SetNextSibling(nullptr); + if (childrenTail_ == view) { + childrenTail_ = node; + } + childrenNum_--; + OnChildChanged(); + return; + } + node = node->GetNextSibling(); + } +} + +void UIViewGroup::RemoveAll() +{ + UIView* node = childrenHead_; + childrenHead_ = nullptr; + childrenTail_ = nullptr; + childrenNum_ = 0; + UIView* tmp = nullptr; + while (node != nullptr) { + tmp = node; + node = node->GetNextSibling(); + tmp->SetParent(nullptr); + tmp->SetNextSibling(nullptr); + } + OnChildChanged(); +} + +void UIViewGroup::GetTargetView(const Point& point, UIView** last) +{ + if (last == nullptr) { + return; + } + + Rect rect = GetRect(); + if (disallowIntercept_) { + *last = nullptr; + return; + } + if (!rect.IsContains(point)) { + return; + } + if (!visible_) { + return; + } + if (touchable_) { + *last = this; + } + if (isDragging_) { + return; + } + UIView* view = childrenHead_; + while (view != nullptr) { + if (!view->IsViewGroup()) { + rect = view->GetRect(); + if (rect.IsContains(point)) { + view->GetTargetView(point, last); + } + } else { + UIViewGroup* viewGroup = static_cast(view); + viewGroup->GetTargetView(point, last); + } + view = view->GetNextSibling(); + } +} + +void UIViewGroup::GetTargetView(const Point& point, UIView** current, UIView** target) +{ + if ((current == nullptr) || (target == nullptr)) { + return; + } + + Rect rect = GetRect(); + if (disallowIntercept_) { + *current = nullptr; + *target = nullptr; + return; + } + if (!rect.IsContains(point)) { + return; + } + if (!visible_) { + return; + } + *target = this; + if (touchable_) { + *current = this; + } + if (isDragging_) { + return; + } + UIView* view = childrenHead_; + while (view != nullptr) { + if (!view->IsViewGroup()) { + rect = view->GetRect(); + if (rect.IsContains(point)) { + view->GetTargetView(point, current, target); + } + } else { + UIViewGroup* viewGroup = static_cast(view); + viewGroup->GetTargetView(point, current, target); + } + view = view->GetNextSibling(); + } +} + +Rect UIViewGroup::GetAllChildRelativeRect() const +{ + Rect rect; + UIView* view = childrenHead_; + if (view != nullptr) { + rect = view->GetRelativeRect(); + view = view->GetNextSibling(); + } + while (view != nullptr) { + Rect rectChild = view->GetRelativeRect(); + rect.Join(rect, rectChild); + view = view->GetNextSibling(); + } + return rect; +} + +UIView* UIViewGroup::GetChildById(const char* id) const +{ + if (id == nullptr || childrenHead_ == nullptr) { + return nullptr; + } + UIView* child = childrenHead_; + while (child != nullptr) { + if ((child->GetViewId() != nullptr) && !strcmp(child->GetViewId(), id)) { + return child; + } else if (child->IsViewGroup() && static_cast(child)->GetChildrenHead() != nullptr) { + child = static_cast(child)->GetChildrenHead(); + continue; + } else if (child->GetNextSibling() != nullptr) { + child = child->GetNextSibling(); + continue; + } + while (child->GetParent() != this && child->GetParent()->GetNextSibling() == nullptr) { + child = child->GetParent(); + } + if (child->GetParent() != this) { + child = child->GetParent()->GetNextSibling(); + continue; + } + break; + } + return nullptr; +} + +void UIViewGroup::MoveChildByOffset(int16_t xOffset, int16_t yOffset) +{ + UIView* view = childrenHead_; + int16_t x; + int16_t y; + while (view != nullptr) { + x = view->GetX() + xOffset; + y = view->GetY() + yOffset; + view->SetPosition(x, y); + view = view->GetNextSibling(); + } +} + +void UIViewGroup::AutoResize() +{ + Rect rect = GetAllChildRelativeRect(); + SetWidth(rect.GetWidth() + rect.GetLeft()); + SetHeight(rect.GetHeight() + rect.GetTop()); +} +} // namespace OHOS diff --git a/frameworks/core/render_manager.cpp b/frameworks/core/render_manager.cpp new file mode 100755 index 0000000..9714517 --- /dev/null +++ b/frameworks/core/render_manager.cpp @@ -0,0 +1,230 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "core/render_manager.h" + +#include "components/root_view.h" +#include "dock/screen_device_proxy.h" +#include "graphic_log.h" +#include "hal_tick.h" +#include "securec.h" +#if ENABLE_WINDOW +#include "window/window_impl.h" +#endif + +namespace OHOS { +RenderManager::RenderManager() : fps_(0.f), needResetFPS_(true), onFPSChangedListener_(nullptr) {} + +RenderManager::~RenderManager() {} + +void RenderManager::Init() +{ + Task::Init(); +} + +void RenderManager::RenderTask() +{ +#if ENABLE_WINDOW + ListNode* winNode = winList_.Begin(); + while (winNode != winList_.End()) { + WindowImpl* windowImpl = reinterpret_cast(winNode->data_); + windowImpl->Render(); + winNode = winNode->next_; + } +#else + RootView::GetInstance()->Measure(); + RootView::GetInstance()->Render(); +#endif + +#if ENABLE_FPS_SUPPORT + UpdateFPS(); +#endif +} + +#if ENABLE_FPS_SUPPORT +void RenderManager::UpdateFPS() +{ + SysInfo::FPSCalculateType type = SysInfo::FPS_CT_FIXED_TIME; + if (onFPSChangedListener_) { + type = onFPSChangedListener_->GetFPSCalculateType(); + } + if (type == SysInfo::FPS_CT_FIXED_TIME) { + UpdateFPSByFixedTimeMethod(); + } else if (type == SysInfo::FPS_CT_AVERAGE_SAMPLING) { + UpdateFPSByAverageSamplingMethod(); + } else if (type == SysInfo::FPS_CT_PRECISE_SAMPLING) { + UpdateFPSByPreciseSamplingMethod(); + } + OnFPSChanged(fps_); +} + +void RenderManager::UpdateFPSByFixedTimeMethod() +{ + static uint16_t frameCount = 0; + static uint32_t lastTime = HALTick::GetInstance().GetTime(); + if (needResetFPS_) { + frameCount = 0; + lastTime = HALTick::GetInstance().GetTime(); + needResetFPS_ = false; + fps_ = 0.f; + return; + } + + frameCount++; + + uint32_t curTime = HALTick::GetInstance().GetTime(); + if (curTime - lastTime > MILLISECONDS_PER_SECOND) { + fps_ = 1.f * frameCount / (curTime - lastTime) * MILLISECONDS_PER_SECOND; + fps_ = (fps_ > MAX_FPS) ? MAX_FPS : fps_; + frameCount = 0; + lastTime = curTime; + } +} + +void RenderManager::UpdateFPSByAverageSamplingMethod() +{ + static float avgDuration = 0.f; + static float alpha = 1.f / SAMPLE_NUMBER; + static bool firstFrame = true; + static uint32_t lastTime = HALTick::GetInstance().GetTime(); + if (needResetFPS_) { + avgDuration = 0.f; + alpha = 1.f / SAMPLE_NUMBER; + firstFrame = true; + lastTime = HALTick::GetInstance().GetTime(); + needResetFPS_ = false; + fps_ = 0.f; + return; + } + uint32_t curTime = HALTick::GetInstance().GetTime(); + int deltaTime = curTime - lastTime; + lastTime = curTime; + + if (firstFrame) { + avgDuration = static_cast(deltaTime); + firstFrame = false; + } else { + avgDuration = avgDuration * (1 - alpha) + deltaTime * alpha; + } + fps_ = 1.f / avgDuration * MILLISECONDS_PER_SECOND; +} + +void RenderManager::UpdateFPSByPreciseSamplingMethod() +{ + static int deltaTimeQueue[SAMPLE_NUMBER] = {0}; + static int frameCount = 0; + static int sumDuration = 0; + static bool isQueueFull = false; + static uint32_t lastTime = HALTick::GetInstance().GetTime(); + if (needResetFPS_) { + if (memset_s(deltaTimeQueue, sizeof(deltaTimeQueue), 0, sizeof(deltaTimeQueue)) != EOK) { + return; + } + frameCount = 0; + sumDuration = 0; + isQueueFull = false; + lastTime = HALTick::GetInstance().GetTime(); + needResetFPS_ = false; + fps_ = 0.f; + return; + } + uint32_t curTime = HALTick::GetInstance().GetTime(); + int deltaTime = curTime - lastTime; + lastTime = curTime; + + if (!isQueueFull && (frameCount == SAMPLE_NUMBER)) { + isQueueFull = true; + } + frameCount %= SAMPLE_NUMBER; + sumDuration -= deltaTimeQueue[frameCount]; + sumDuration += deltaTime; + deltaTimeQueue[frameCount++] = deltaTime; + if (isQueueFull) { + fps_ = 1.f * SAMPLE_NUMBER / sumDuration * MILLISECONDS_PER_SECOND; + } else { + fps_ = 1.f * frameCount / sumDuration * MILLISECONDS_PER_SECOND; + } +} +#endif + +void RenderManager::RenderRect(const Rect& rect, RootView* rootView) +{ + if (rootView == nullptr) { + return; + } + + Rect mask = rect; +#if ENABLE_WINDOW + if (rootView->GetBoundWindow()) { + Rect winRect = rootView->GetBoundWindow()->GetRect(); + winRect.SetPosition(0, 0); + mask.Intersect(rect, winRect); + } +#endif + int32_t bufferHeight = ScreenDeviceProxy::GetInstance()->GetScreenArea() / mask.GetWidth(); + if (bufferHeight > mask.GetHeight()) { + bufferHeight = mask.GetHeight(); + } + + Rect& bufferRect = ScreenDeviceProxy::GetInstance()->GetBufferRect(); + bufferRect.SetLeft(mask.GetLeft()); + bufferRect.SetRight(mask.GetRight()); + + int16_t bottom = mask.GetBottom(); + for (int16_t bufferTop = mask.GetTop(); bufferTop <= bottom; bufferTop += bufferHeight) { + bufferRect.SetTop(bufferTop); + int16_t bufferBottom = bufferTop + bufferHeight - 1; + if (bufferBottom >= bottom) { + bufferRect.SetBottom(bottom); + } else { + bufferRect.SetBottom(bufferBottom); + } +#if LOCAL_RENDER + rootView->DrawInvalidMap(bufferRect); +#else + UIView* topView = rootView->GetTopUIView(bufferRect); + rootView->DrawTop(topView, bufferRect); +#endif +#if !ENABLE_WINDOW + ScreenDeviceProxy::GetInstance()->Flush(); +#endif + } +} + +#if ENABLE_WINDOW +void RenderManager::AddToDisplay(Window* window) +{ + if (window == nullptr) { + return; + } + winList_.PushBack(window); +} + +void RenderManager::RemoveFromDisplay(Window* window) +{ + if (window == nullptr) { + return; + } + ListNode* winNode = winList_.Begin(); + while (winNode != winList_.End()) { + if (winNode->data_ == window) { + winList_.Remove(winNode); + return; + } + winNode = winNode->next_; + } +} +#endif +} // namespace OHOS diff --git a/frameworks/core/render_manager.h b/frameworks/core/render_manager.h new file mode 100755 index 0000000..23ac038 --- /dev/null +++ b/frameworks/core/render_manager.h @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef GRAPHIC_LITE_RENDER_MANAGER_H +#define GRAPHIC_LITE_RENDER_MANAGER_H + +#include "components/ui_view.h" +#include "components/root_view.h" +#include "common/task_manager.h" +#include "geometry2d.h" +#include "list.h" +#include "sys_info.h" +#if ENABLE_WINDOW +#include "window/window.h" +#endif + +namespace OHOS { +static constexpr float MAX_FPS = 90.f; + +static constexpr int16_t SAMPLE_NUMBER = 100; + +static constexpr uint16_t MILLISECONDS_PER_SECOND = 1000; + +class RenderManager : public Task { +public: + static RenderManager& GetInstance() + { + static RenderManager instance; + return instance; + } + + virtual void Init() override; + +#if ENABLE_WINDOW + Window* GetWindowById(int32_t id) + { + auto node = winList_.Begin(); + while (node != winList_.End()) { + if (node->data_->GetWindowId() == id) { + return node->data_; + } + node = node->next_; + } + return nullptr; + } +#endif + + virtual void Callback() override + { + RenderTask(); + } + + float GetFPS() const + { + return fps_; + } + + void RegisterFPSChangedListener(SysInfo::OnFPSChangedListener* onFPSChangedListener) + { + onFPSChangedListener_ = onFPSChangedListener; + needResetFPS_ = true; + } + +#if ENABLE_WINDOW + void AddToDisplay(Window* window); + + void RemoveFromDisplay(Window* window); +#endif + +private: + friend class RootView; + + RenderManager(); + + ~RenderManager(); + + void RenderTask(); + + static void RenderRect(const Rect& rect, RootView* rootView); + +#if ENABLE_FPS_SUPPORT + void UpdateFPS(); + + void UpdateFPSByFixedTimeMethod(); + + void UpdateFPSByAverageSamplingMethod(); + + void UpdateFPSByPreciseSamplingMethod(); + + void OnFPSChanged(float newFPS) + { + if (onFPSChangedListener_) { + onFPSChangedListener_->OnFPSChanged(newFPS); + } + } +#endif + + float fps_; + + bool needResetFPS_; + + SysInfo::OnFPSChangedListener* onFPSChangedListener_; + +#if ENABLE_WINDOW + List winList_; +#endif +}; +} // namespace OHOS +#endif // GRAPHIC_LITE_RENDER_MANAGER_H diff --git a/frameworks/core/task_manager.cpp b/frameworks/core/task_manager.cpp new file mode 100755 index 0000000..2035f40 --- /dev/null +++ b/frameworks/core/task_manager.cpp @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "common/task_manager.h" +#include +#include "hal_tick.h" + +namespace OHOS { +void TaskManager::Add(Task* task) +{ + if (task == nullptr) { + return; + } + + list_.PushBack(task); +} + +void TaskManager::Remove(Task* task) +{ + if (task == nullptr) { + return; + } + ListNode* pos = list_.Begin(); + while (pos != list_.End()) { + if (pos->data_ == task) { + list_.Remove(pos); + return; + } + pos = pos->next_; + } +} + +void TaskManager::TaskHandler() +{ + if (!canTaskRun_) { + return; + } + + if (isHandlerRunning_) { + return; + } + isHandlerRunning_ = true; + + ListNode* node = list_.Begin(); + + while (node != list_.End()) { + Task* currentTask = node->data_; + currentTask->TaskExecute(); + + node = node->next_; + } + + isHandlerRunning_ = false; +} +} diff --git a/frameworks/default_resource/check_box_res.cpp b/frameworks/default_resource/check_box_res.cpp new file mode 100755 index 0000000..ae5be9a --- /dev/null +++ b/frameworks/default_resource/check_box_res.cpp @@ -0,0 +1,1379 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "default_resource/check_box_res.h" +namespace OHOS { +const uint8_t CHECK_BOX_ON_MAP[] = { + /* Pixel format: ARGB8888 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x74, 0x23, + 0x2c, 0xff, 0x71, 0x20, 0x90, 0xff, 0x72, 0x1f, 0xd5, 0xff, 0x71, 0x1f, 0xf3, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, + 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, + 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, + 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, + 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, + 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, + 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xf3, 0xff, 0x72, 0x1f, 0xd5, + 0xff, 0x71, 0x20, 0x90, 0xff, 0x74, 0x23, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0x80, 0x2b, 0x06, 0xff, 0x73, 0x21, 0x95, 0xff, 0x72, 0x1f, 0xfd, 0xff, 0x71, 0x1f, + 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, + 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, + 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, + 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, + 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, + 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, + 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, + 0xff, 0x72, 0x1f, 0xfd, 0xff, 0x72, 0x1f, 0x94, 0xff, 0x80, 0x2b, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x80, 0x2b, 0x06, + 0xff, 0x71, 0x1f, 0xbd, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, + 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, + 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, + 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, + 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, + 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, + 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, + 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, + 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xbd, 0xff, 0x80, 0x2b, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x73, 0x21, 0x95, 0xff, 0x71, 0x1f, 0xff, + 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, + 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, + 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, + 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, + 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, + 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, + 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, + 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, + 0xff, 0x71, 0x1f, 0xff, 0xff, 0x72, 0x1f, 0x94, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xff, 0x74, 0x23, 0x2c, 0xff, 0x72, 0x1f, 0xfd, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, + 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, + 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, + 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, + 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, + 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, + 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, + 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, + 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, + 0xff, 0x72, 0x1f, 0xfd, 0xff, 0x74, 0x23, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, + 0x71, 0x20, 0x90, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, + 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, + 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, + 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, + 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, + 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, + 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, + 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, + 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, + 0xff, 0x71, 0x20, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x72, 0x1f, 0xd5, 0xff, + 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, + 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, + 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, + 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, + 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, + 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, + 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, + 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, + 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x72, 0x1f, 0xd5, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x71, 0x1f, 0xf3, 0xff, 0x71, 0x1f, 0xff, 0xff, + 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, + 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, + 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, + 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, + 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, + 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, + 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, + 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, + 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xf3, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, + 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, + 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, + 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, + 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, + 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, + 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, + 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, + 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, + 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, + 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, + 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, + 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, + 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, + 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, + 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, + 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, + 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, + 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x71, + 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, + 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, + 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, + 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, + 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, + 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, + 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, + 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, + 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, + 0x71, 0x1f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, + 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, + 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, + 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, + 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, + 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, + 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, + 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, + 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, + 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, + 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, + 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, + 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, + 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, + 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, + 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, + 0xff, 0x71, 0x1f, 0xff, 0xff, 0x83, 0x3b, 0xff, 0xff, 0x78, 0x2a, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, + 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, + 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, + 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, + 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, + 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, + 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, + 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, + 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x79, 0x2c, 0xff, 0xff, 0xdb, 0xc7, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xf7, 0xf3, 0xff, 0xff, 0x99, 0x5f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, + 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, + 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, + 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, + 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, + 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, + 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, + 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, + 0x71, 0x1f, 0xff, 0xff, 0x76, 0x26, 0xff, 0xff, 0xdd, 0xc9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xe6, 0xd8, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, + 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, + 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x71, 0x1f, + 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, + 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, + 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, + 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, + 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, + 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x73, 0x23, 0xff, 0xff, + 0xd5, 0xbd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xe7, 0xd9, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, + 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, + 0x1f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, + 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, + 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, + 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, + 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, + 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, + 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x72, 0x20, 0xff, 0xff, 0xcd, 0xb1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xfe, 0xff, 0xff, 0x9e, 0x66, 0xff, + 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, + 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, + 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, + 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, + 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, + 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, + 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, + 0x1f, 0xff, 0xff, 0xc5, 0xa3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xac, 0x7c, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, + 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, + 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, + 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, + 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, + 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, + 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, + 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0xbc, 0x95, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xb6, 0x8b, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, + 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, + 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, + 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, + 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, + 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, + 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, + 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0xb2, 0x85, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0x9a, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, + 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, + 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, + 0xff, 0xff, 0x71, 0x1f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x71, 0x1f, 0xff, + 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, + 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x9e, 0x66, 0xff, 0xff, 0xd9, + 0xc4, 0xff, 0xff, 0xcb, 0xae, 0xff, 0xff, 0x82, 0x3a, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, + 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, + 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0xa9, 0x77, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xc8, 0xa8, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, + 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, + 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, + 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, + 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, + 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x87, 0x42, 0xff, 0xff, 0xfd, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xf1, 0xe9, 0xff, 0xff, 0x8a, 0x46, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, + 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, + 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0xa0, 0x6a, 0xff, 0xff, 0xfd, 0xfd, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xd1, 0xb6, 0xff, 0xff, 0x72, + 0x21, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, + 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, + 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, + 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, + 0xff, 0xff, 0xa1, 0x6b, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xf5, 0xf0, 0xff, 0xff, 0x90, 0x50, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, + 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, + 0xff, 0x99, 0x5e, 0xff, 0xff, 0xfc, 0xfa, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xd8, 0xc2, 0xff, 0xff, 0x74, 0x24, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, + 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, + 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, + 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, + 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x7e, 0x34, + 0xff, 0xff, 0xf5, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xf8, 0xf5, 0xff, 0xff, 0x96, 0x5a, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, + 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x91, 0x52, 0xff, 0xff, 0xf9, 0xf6, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0xcd, + 0xff, 0xff, 0x77, 0x28, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, + 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, + 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, + 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, + 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, + 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x90, 0x51, + 0xff, 0xff, 0xf5, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xfb, 0xf9, 0xff, 0xff, 0x9e, 0x67, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, + 0x71, 0x1f, 0xff, 0xff, 0x8b, 0x48, 0xff, 0xff, 0xf6, 0xf1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe5, 0xd7, 0xff, 0xff, 0x7a, 0x2d, 0xff, 0xff, 0x71, 0x1f, + 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, + 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, + 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, + 0xff, 0x71, 0x1f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x71, 0x1f, 0xff, 0xff, + 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, + 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x8a, 0x46, + 0xff, 0xff, 0xf1, 0xe9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xfd, 0xfc, 0xff, 0xff, 0xa7, 0x74, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x85, 0x3f, 0xff, 0xff, + 0xf2, 0xeb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xeb, 0xe0, 0xff, 0xff, 0x7e, 0x34, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, + 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, + 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, + 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, + 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, + 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x84, 0x3d, + 0xff, 0xff, 0xed, 0xe2, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xfe, 0xfe, 0xff, 0xff, 0xb9, 0x91, 0xff, 0xff, 0xed, 0xe3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xe8, 0xff, 0xff, 0x83, 0x3b, 0xff, + 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, + 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, + 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, + 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, + 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, + 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x80, 0x36, + 0xff, 0xff, 0xe7, 0xda, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xf4, 0xee, 0xff, 0xff, 0x88, 0x44, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, + 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, + 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, + 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, + 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, + 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, + 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x7b, 0x2f, + 0xff, 0xff, 0xe1, 0xd0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0xf4, 0xff, 0xff, + 0x8f, 0x4e, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, + 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, + 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, + 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, + 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x71, + 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, + 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, + 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x78, 0x2a, + 0xff, 0xff, 0xda, 0xc5, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xf8, 0xff, 0xff, 0x95, 0x58, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, + 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, + 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, + 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, + 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, + 0x71, 0x1f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, + 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, + 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, + 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x74, 0x25, + 0xff, 0xff, 0xd3, 0xb9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, + 0xfc, 0xff, 0xff, 0x9c, 0x64, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, + 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, + 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, + 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, + 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, + 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, + 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, + 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x73, 0x22, + 0xff, 0xff, 0xc3, 0xa1, 0xff, 0xff, 0xfd, 0xfd, 0xff, 0xff, 0xf6, 0xf0, 0xff, 0xff, 0xa1, 0x6b, 0xff, 0xff, 0x71, + 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, + 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, + 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, + 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, + 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, + 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, + 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, + 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, + 0xff, 0xff, 0x76, 0x26, 0xff, 0xff, 0x72, 0x21, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, + 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, + 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, + 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, + 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, + 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, + 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, + 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, + 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, + 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, + 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, + 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, + 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, + 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, + 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x71, 0x1f, + 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, + 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, + 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, + 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, + 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, + 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, + 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, + 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, + 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, + 0x1f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, + 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, + 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, + 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, + 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, + 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, + 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, + 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, + 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, + 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x71, 0x1f, 0xf3, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, + 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, + 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, + 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, + 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, + 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, + 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, + 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, + 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, + 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xf3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0x72, 0x1f, 0xd5, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, + 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, + 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, + 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, + 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, + 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, + 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, + 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, + 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, + 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x72, 0x1f, 0xd5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0x71, 0x20, 0x90, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, + 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, + 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, + 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, + 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, + 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, + 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, + 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, + 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, + 0xff, 0xff, 0x71, 0x20, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x74, 0x23, 0x2c, + 0xff, 0x72, 0x1f, 0xfd, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, + 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, + 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, + 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, + 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, + 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, + 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, + 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, + 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x72, 0x1f, 0xfd, 0xff, 0x74, 0x23, + 0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x73, 0x21, 0x95, + 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, + 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, + 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, + 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, + 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, + 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, + 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, + 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, + 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x72, 0x1f, 0x94, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x80, 0x2b, 0x06, 0xff, 0x71, 0x1f, 0xbd, + 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, + 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, + 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, + 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, + 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, + 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, + 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, + 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, + 0xff, 0x71, 0x1f, 0xbd, 0xff, 0x80, 0x2b, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x80, 0x2b, 0x06, 0xff, 0x73, 0x21, 0x95, + 0xff, 0x72, 0x1f, 0xfd, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, + 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, + 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, + 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, + 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, + 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, + 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, + 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x72, 0x1f, 0xfd, 0xff, 0x72, 0x1f, 0x94, 0xff, 0x80, 0x2b, 0x06, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x74, 0x23, 0x2c, + 0xff, 0x71, 0x20, 0x90, 0xff, 0x72, 0x1f, 0xd5, 0xff, 0x71, 0x1f, 0xf3, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, + 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, + 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, + 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, + 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, + 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, + 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xff, 0xff, 0x71, 0x1f, 0xf3, 0xff, 0x72, 0x1f, 0xd5, 0xff, + 0x71, 0x20, 0x90, 0xff, 0x74, 0x23, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, +}; + +const uint8_t CHECK_BOX_OFF_MAP[] = { + /* Pixel format: ARGB8888 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, + 0x02, 0xff, 0xff, 0xff, 0x38, 0xff, 0xff, 0xff, 0x6f, 0xff, 0xff, 0xff, 0x93, 0xff, 0xff, 0xff, 0xa3, 0xff, 0xff, + 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, + 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, + 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, + 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, + 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, + 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa3, 0xff, 0xff, 0xff, 0x93, 0xff, 0xff, 0xff, 0x6f, + 0xff, 0xff, 0xff, 0x38, 0xff, 0xff, 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x24, 0xff, 0xff, 0xff, 0x8b, 0xff, 0xff, 0xff, + 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, + 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, + 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, + 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, + 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, + 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, + 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, + 0xff, 0xff, 0xff, 0x8b, 0xff, 0xff, 0xff, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0x37, 0xff, 0xff, 0xff, 0xa3, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, + 0x8a, 0xff, 0xff, 0xff, 0x50, 0xff, 0xff, 0xff, 0x31, 0xff, 0xff, 0xff, 0x23, 0xff, 0xff, 0xff, 0x22, 0xff, 0xff, + 0xff, 0x22, 0xff, 0xff, 0xff, 0x22, 0xff, 0xff, 0xff, 0x22, 0xff, 0xff, 0xff, 0x22, 0xff, 0xff, 0xff, 0x22, 0xff, + 0xff, 0xff, 0x22, 0xff, 0xff, 0xff, 0x22, 0xff, 0xff, 0xff, 0x22, 0xff, 0xff, 0xff, 0x22, 0xff, 0xff, 0xff, 0x22, + 0xff, 0xff, 0xff, 0x22, 0xff, 0xff, 0xff, 0x22, 0xff, 0xff, 0xff, 0x22, 0xff, 0xff, 0xff, 0x22, 0xff, 0xff, 0xff, + 0x22, 0xff, 0xff, 0xff, 0x22, 0xff, 0xff, 0xff, 0x22, 0xff, 0xff, 0xff, 0x22, 0xff, 0xff, 0xff, 0x22, 0xff, 0xff, + 0xff, 0x22, 0xff, 0xff, 0xff, 0x22, 0xff, 0xff, 0xff, 0x22, 0xff, 0xff, 0xff, 0x22, 0xff, 0xff, 0xff, 0x23, 0xff, + 0xff, 0xff, 0x31, 0xff, 0xff, 0xff, 0x50, 0xff, 0xff, 0xff, 0x8a, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, + 0xff, 0xff, 0xff, 0xa3, 0xff, 0xff, 0xff, 0x37, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x24, 0xff, 0xff, 0xff, 0xa3, + 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa1, 0xff, 0xff, 0xff, 0x3d, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x01, 0xff, 0xff, 0xff, 0x3d, 0xff, 0xff, 0xff, 0xa1, 0xff, 0xff, 0xff, 0xa8, + 0xff, 0xff, 0xff, 0xa3, 0xff, 0xff, 0xff, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x02, 0xff, 0xff, 0xff, 0x8b, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa1, + 0xff, 0xff, 0xff, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x21, 0xff, 0xff, 0xff, 0xa1, 0xff, 0xff, 0xff, 0xa8, + 0xff, 0xff, 0xff, 0x8b, 0xff, 0xff, 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, + 0xff, 0xff, 0x38, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x3d, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, + 0xff, 0xff, 0xff, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x6f, 0xff, + 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0x8a, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x01, 0xff, 0xff, 0xff, 0x8a, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0x6f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x93, 0xff, 0xff, 0xff, 0xa8, 0xff, + 0xff, 0xff, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x50, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0x93, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xa3, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0x31, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, + 0xff, 0xff, 0x31, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x23, 0xff, + 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, + 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x22, 0xff, 0xff, 0xff, 0xa8, 0xff, + 0xff, 0xff, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, + 0xff, 0xa8, 0xff, 0xff, 0xff, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x22, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, + 0xff, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xff, 0xff, 0xff, 0x22, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0x22, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, + 0xff, 0x22, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x22, 0xff, 0xff, + 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, + 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x22, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, + 0xff, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, + 0xa8, 0xff, 0xff, 0xff, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x22, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, + 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xff, 0xff, 0xff, 0x22, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0x22, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, + 0x22, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x22, 0xff, 0xff, 0xff, + 0xa8, 0xff, 0xff, 0xff, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xa8, + 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x22, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, + 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, + 0xff, 0xff, 0xff, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x22, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0x22, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0x22, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0x22, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x22, + 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, + 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x22, 0xff, 0xff, 0xff, 0xa8, + 0xff, 0xff, 0xff, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xa8, 0xff, + 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x22, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, + 0xff, 0xff, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x22, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0x22, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, + 0xff, 0xff, 0x22, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x22, 0xff, + 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, + 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x22, 0xff, 0xff, 0xff, 0xa8, 0xff, + 0xff, 0xff, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, + 0xff, 0xa8, 0xff, 0xff, 0xff, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x22, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, + 0xff, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xff, 0xff, 0xff, 0x22, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0x22, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, + 0xff, 0x22, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x22, 0xff, 0xff, + 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, + 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x23, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, + 0xff, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xa3, 0xff, 0xff, 0xff, + 0xa8, 0xff, 0xff, 0xff, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x31, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa3, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x93, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, + 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xff, 0xff, 0xff, 0x50, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0x93, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x6f, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0x8a, 0xff, 0xff, 0xff, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x01, 0xff, 0xff, 0xff, + 0x8a, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0x38, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0x3d, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x3d, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, + 0xa8, 0xff, 0xff, 0xff, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x02, + 0xff, 0xff, 0xff, 0x8b, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa1, 0xff, 0xff, 0xff, 0x21, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0x21, 0xff, 0xff, 0xff, 0xa1, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0x8b, 0xff, 0xff, 0xff, + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x24, + 0xff, 0xff, 0xff, 0xa3, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa1, 0xff, 0xff, 0xff, 0x3c, 0xff, 0xff, 0xff, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x01, 0xff, 0xff, 0xff, 0x3d, 0xff, 0xff, 0xff, 0xa1, + 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa3, 0xff, 0xff, 0xff, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x37, + 0xff, 0xff, 0xff, 0xa3, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0x8a, 0xff, 0xff, 0xff, + 0x50, 0xff, 0xff, 0xff, 0x31, 0xff, 0xff, 0xff, 0x23, 0xff, 0xff, 0xff, 0x22, 0xff, 0xff, 0xff, 0x22, 0xff, 0xff, + 0xff, 0x22, 0xff, 0xff, 0xff, 0x22, 0xff, 0xff, 0xff, 0x22, 0xff, 0xff, 0xff, 0x22, 0xff, 0xff, 0xff, 0x22, 0xff, + 0xff, 0xff, 0x22, 0xff, 0xff, 0xff, 0x22, 0xff, 0xff, 0xff, 0x22, 0xff, 0xff, 0xff, 0x22, 0xff, 0xff, 0xff, 0x22, + 0xff, 0xff, 0xff, 0x22, 0xff, 0xff, 0xff, 0x22, 0xff, 0xff, 0xff, 0x22, 0xff, 0xff, 0xff, 0x22, 0xff, 0xff, 0xff, + 0x22, 0xff, 0xff, 0xff, 0x22, 0xff, 0xff, 0xff, 0x22, 0xff, 0xff, 0xff, 0x22, 0xff, 0xff, 0xff, 0x22, 0xff, 0xff, + 0xff, 0x22, 0xff, 0xff, 0xff, 0x22, 0xff, 0xff, 0xff, 0x22, 0xff, 0xff, 0xff, 0x23, 0xff, 0xff, 0xff, 0x31, 0xff, + 0xff, 0xff, 0x50, 0xff, 0xff, 0xff, 0x8a, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa3, + 0xff, 0xff, 0xff, 0x37, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x24, + 0xff, 0xff, 0xff, 0x8b, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, + 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, + 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, + 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, + 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, + 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, + 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, + 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0x8b, 0xff, 0xff, 0xff, 0x24, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x02, + 0xff, 0xff, 0xff, 0x38, 0xff, 0xff, 0xff, 0x6f, 0xff, 0xff, 0xff, 0x93, 0xff, 0xff, 0xff, 0xa3, 0xff, 0xff, 0xff, + 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, + 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, + 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, + 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, + 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, + 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa8, 0xff, 0xff, 0xff, 0xa3, 0xff, 0xff, 0xff, 0x93, 0xff, 0xff, 0xff, 0x6f, 0xff, + 0xff, 0xff, 0x38, 0xff, 0xff, 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, +}; + +ImageInfo g_checkBoxOn = {{0}}; + +ImageInfo* GetCheckBoxOnInfo() +{ + /* 56 : check box width */ + g_checkBoxOn.header.width = 56; + /* 56 : check box heigh */ + g_checkBoxOn.header.height = 56; + /* 5 : check box cf format */ + g_checkBoxOn.header.colorMode = ARGB8888; + /* 12544 : check box size */ + g_checkBoxOn.dataSize = 12544; + g_checkBoxOn.data = CHECK_BOX_ON_MAP; + return &g_checkBoxOn; +} + +ImageInfo g_checkBoxOff = {{0}}; + +ImageInfo* GetCheckBoxOffInfo() +{ + /* 56 : check box width */ + g_checkBoxOff.header.width = 56; + /* 56 : check box heigh */ + g_checkBoxOff.header.height = 56; + /* 5 : check box cf format */ + g_checkBoxOff.header.colorMode = ARGB8888; + /* 12544 : check box size */ + g_checkBoxOff.dataSize = 12544; + g_checkBoxOff.data = CHECK_BOX_OFF_MAP; + return &g_checkBoxOff; +} +} \ No newline at end of file diff --git a/frameworks/default_resource/check_box_res.h b/frameworks/default_resource/check_box_res.h new file mode 100755 index 0000000..233e46d --- /dev/null +++ b/frameworks/default_resource/check_box_res.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef GRAPHIC_LITE_CHECK_BOX_RES_H +#define GRAPHIC_LITE_CHECK_BOX_RES_H + +#include "image_info.h" +#include "graphic_types.h" +namespace OHOS { +ImageInfo* GetCheckBoxOnInfo(); +ImageInfo* GetCheckBoxOffInfo(); +} // namespace OHOS +#endif // GRAPHIC_LITE_CHECK_BOX_RES_H diff --git a/frameworks/dfx/event_injector.cpp b/frameworks/dfx/event_injector.cpp new file mode 100755 index 0000000..01d44bc --- /dev/null +++ b/frameworks/dfx/event_injector.cpp @@ -0,0 +1,269 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "dfx/event_injector.h" +#if ENABLE_DEBUG +#include "common/input_device_manager.h" +#include "dfx/key_event_injector.h" +#include "dfx/point_event_injector.h" +#include "graphic_log.h" + +namespace OHOS { +EventInjector::~EventInjector() +{ + if (pointEventInjector_ != nullptr) { + InputDeviceManager::GetInstance()->Remove(pointEventInjector_); + delete pointEventInjector_; + pointEventInjector_ = nullptr; + } + if (keyEventInjector_ != nullptr) { + InputDeviceManager::GetInstance()->Remove(keyEventInjector_); + delete keyEventInjector_; + keyEventInjector_ = nullptr; + } +} + +bool EventInjector::RegisterEventInjector(EventDataType type) +{ + switch (type) { + case EventDataType::POINT_TYPE: + if (pointEventInjector_ == nullptr) { + pointEventInjector_ = new PointEventInjector(); + if (pointEventInjector_ == nullptr) { + GRAPHIC_LOGE("EventInjector::RegisterEventInjector register pointEventInjector failed Err!\n"); + return false; + } + InputDeviceManager::GetInstance()->Add(pointEventInjector_); + } + return true; + case EventDataType::KEY_TYPE: + if (keyEventInjector_ == nullptr) { + keyEventInjector_ = new KeyEventInjector(); + if (keyEventInjector_ == nullptr) { + GRAPHIC_LOGE("EventInjector::RegisterEventInjector register keyEventInjector failed Err!\n"); + return false; + } + InputDeviceManager::GetInstance()->Add(keyEventInjector_); + } + return true; + default: + break; + } + return false; +} + +void EventInjector::UnregisterEventInjector(EventDataType type) +{ + switch (type) { + case EventDataType::POINT_TYPE: + if (pointEventInjector_ != nullptr) { + InputDeviceManager::GetInstance()->Remove(pointEventInjector_); + delete pointEventInjector_; + pointEventInjector_ = nullptr; + } + break; + case EventDataType::KEY_TYPE: + if (keyEventInjector_ != nullptr) { + InputDeviceManager::GetInstance()->Remove(keyEventInjector_); + delete keyEventInjector_; + keyEventInjector_ = nullptr; + } + break; + default: + break; + } +} + +bool EventInjector::IsEventInjectorRegistered(EventDataType type) const +{ + switch (type) { + case EventDataType::POINT_TYPE: + if (pointEventInjector_ != nullptr) { + return true; + } + break; + case EventDataType::KEY_TYPE: + if (keyEventInjector_ != nullptr) { + return true; + } + break; + default: + break; + } + return false; +} + +bool EventInjector::SetInjectEvent(const DeviceData* dataArray, uint16_t arrayLength, EventDataType type) +{ + if (dataArray == nullptr) { + return false; + } + switch (type) { + case EventDataType::POINT_TYPE: + if (pointEventInjector_ == nullptr) { + return false; + } + for (uint16_t i = 0; i < arrayLength; i++) { + if (!pointEventInjector_->SetPointEvent(dataArray[i])) { + return false; + } + } + break; + case EventDataType::KEY_TYPE: + if (keyEventInjector_ == nullptr) { + return false; + } + for (uint16_t i = 0; i < arrayLength; i++) { + if (!keyEventInjector_->SetKey(dataArray[i])) { + return false; + } + } + break; + default: + return false; + } + return true; +} + +bool EventInjector::SetClickEvent(const Point& clickPoint) +{ + uint16_t clickArrayLen = 2; /* 2:click event point */ + if (clickArrayLen > pointEventInjector_->GetLeftSize()) { + GRAPHIC_LOGE("front points need to be read.(left size in pointer queue is not enough)"); + return false; + } + bool setResult = true; + DeviceData* dataArray = new DeviceData[clickArrayLen]; + if (dataArray == nullptr) { + return false; + } + dataArray[0].point = clickPoint; + dataArray[0].state = InputDevice::STATE_PRESS; + dataArray[1].point = clickPoint; + dataArray[1].state = InputDevice::STATE_RELEASE; + if (!SetInjectEvent(dataArray, clickArrayLen, EventDataType::POINT_TYPE)) { + setResult = false; + } + delete [] dataArray; + return setResult; +} + +bool EventInjector::SetLongPressEvent(const Point& longPressPoint) +{ + uint16_t pointCount = INDEV_LONG_PRESS_TIME / INDEV_READ_PERIOD + 1; + if (pointCount > pointEventInjector_->GetLeftSize()) { + GRAPHIC_LOGE("front points need to be read.(left size in pointer queue is not enough)"); + return false; + } + bool setResult = true; + DeviceData* dataArray = new DeviceData[pointCount]; + if (dataArray == nullptr) { + return false; + } + for (uint16_t i = 0; i < pointCount; i++) { + dataArray[i].point = longPressPoint; + dataArray[i].state = InputDevice::STATE_PRESS; + } + dataArray[pointCount - 1].state = InputDevice::STATE_RELEASE; + if (!SetInjectEvent(dataArray, pointCount, EventDataType::POINT_TYPE)) { + setResult = false; + } + delete [] dataArray; + return setResult; +} + +bool EventInjector::SetDragEvent(const Point& startPoint, const Point& endPoint, uint32_t dragTime) +{ + uint16_t pointCount = (dragTime / INDEV_READ_PERIOD) + 1; + /* 3: at least 3 points in drag event */ + if (pointCount < 3) { + GRAPHIC_LOGE("dragTime is too short.(drag event needs at least 3 points)"); + return false; + } + if (pointCount > pointEventInjector_->GetLeftSize()) { + GRAPHIC_LOGE("dragTime is too long or front points need to be read.(left size in pointer queue is not enough)"); + return false; + } + bool setResult = true; + int16_t negativeFlag = 1; /* 1:represent the coordinate (x, y) of endPoint is larger than startPoint. */ + DeviceData* dataArray = new DeviceData[pointCount]; + if (dataArray == nullptr) { + return false; + } + if (startPoint.x == endPoint.x) { + float pointStep = static_cast(MATH_ABS(endPoint.y - startPoint.y)) / (pointCount - 1); + if (endPoint.y < startPoint.y) { + negativeFlag = -1; /* -1:represent the coordinate y of endPoint is smaller than startPoint. */ + } + for (uint16_t i = 0; i < pointCount; i++) { + dataArray[i].point.x = startPoint.x; + dataArray[i].point.y = startPoint.y + (i * negativeFlag * pointStep); + dataArray[i].state = InputDevice::STATE_PRESS; + } + } else { + float slope = static_cast(endPoint.y - startPoint.y) / (endPoint.x - startPoint.x); + int16_t constPara = startPoint.y - (slope * startPoint.x); + float pointStep = static_cast(MATH_ABS(endPoint.x - startPoint.x)) / (pointCount - 1); + if (endPoint.x < startPoint.x) { + negativeFlag = -1; /* -1:represent the coordinate x of endPoint is smaller than startPoint. */ + } + for (uint16_t i = 0; i < pointCount; i++) { + dataArray[i].point.x = startPoint.x + (i * negativeFlag * pointStep); + dataArray[i].point.y = slope * (dataArray[i].point.x) + constPara; + dataArray[i].state = InputDevice::STATE_PRESS; + } + } + dataArray[pointCount - 1].point = endPoint; + dataArray[pointCount - 1].state = InputDevice::STATE_RELEASE; + if (!SetInjectEvent(dataArray, pointCount, EventDataType::POINT_TYPE)) { + setResult = false; + } + delete [] dataArray; + return setResult; +} + +bool EventInjector::SetKeyEvent(uint16_t keyId, uint16_t state) +{ + uint16_t kevArrayLen = 1; + if (kevArrayLen > keyEventInjector_->GetLeftSize()) { + GRAPHIC_LOGE("front key event need to be read.(left size in key event queue is not enough)"); + return false; + } + bool setResult = true; + DeviceData* dataArray = new DeviceData[kevArrayLen]; + if (dataArray == nullptr) { + return false; + } + for (uint16_t i = 0; i < kevArrayLen; i++) { + dataArray[i].keyId = keyId; + dataArray[i].state = state; + } + if (!SetInjectEvent(dataArray, kevArrayLen, EventDataType::KEY_TYPE)) { + setResult = false; + } + delete [] dataArray; + return setResult; +} + +#if ENABLE_WINDOW +void EventInjector::SetWindowId(uint8_t windowId) +{ + if (pointEventInjector_ != nullptr) { + pointEventInjector_->SetWindowId(windowId); + } +} +#endif +} +#endif // ENABLE_DEBUG \ No newline at end of file diff --git a/frameworks/dfx/key_event_injector.cpp b/frameworks/dfx/key_event_injector.cpp new file mode 100755 index 0000000..4986641 --- /dev/null +++ b/frameworks/dfx/key_event_injector.cpp @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "dfx/key_event_injector.h" +#if ENABLE_DEBUG +#include "graphic_log.h" + +namespace { +const uint8_t MAX_LIST_SIZE = 100; +} + +namespace OHOS { +KeyEventInjector::~KeyEventInjector() +{ + ListNode* node = dataList_.Begin(); + while (node != dataList_.End()) { + if (node->data_ != nullptr) { + DeviceData* deleteData = node->data_; + delete deleteData; + } + node = node->next_; + } + dataList_.Clear(); +} + +bool KeyEventInjector::Read(DeviceData& data) +{ + if (dataList_.IsEmpty()) { + lastState_ = INVALID_KEY_STATE; + } + if (dataList_.Size() > 0) { + lastKeyId_ = dataList_.Front()->keyId; + lastState_ = dataList_.Front()->state; + + ListNode* node = dataList_.Begin(); + if (node->data_ != nullptr) { + DeviceData* deleteData = node->data_; + delete deleteData; + } + dataList_.PopFront(); + } + data.keyId = lastKeyId_; + data.state = lastState_; + return false; +} + +bool KeyEventInjector::SetKey(const DeviceData& data) +{ + if (dataList_.Size() >= MAX_LIST_SIZE) { + GRAPHIC_LOGI("PointEventInjector::SetPointEvent data list is full."); + return false; + } + + DeviceData* tmpData = new DeviceData; + if (tmpData == nullptr) { + GRAPHIC_LOGE("PointEventInjector::SetPointEvent memory allocation failed Err!"); + return false; + } + tmpData->keyId = data.keyId; + tmpData->state = data.state; + dataList_.PushBack(tmpData); + return true; +} + +uint8_t KeyEventInjector::GetLeftSize() const +{ + return MAX_LIST_SIZE - dataList_.Size(); +} +} +#endif // ENABLE_DEBUG \ No newline at end of file diff --git a/frameworks/dfx/key_event_injector.h b/frameworks/dfx/key_event_injector.h new file mode 100755 index 0000000..60f1821 --- /dev/null +++ b/frameworks/dfx/key_event_injector.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef GRAPHIC_LITE_KEY_EVENT_INJECTOR +#define GRAPHIC_LITE_KEY_EVENT_INJECTOR + +#include "graphic_config.h" +#if ENABLE_DEBUG +#include "dock/key_input_device.h" +#include "events/key_event.h" +#include "list.h" + +namespace OHOS { +class KeyEventInjector : public KeyInputDevice { +public: + KeyEventInjector() : lastKeyId_(0), lastState_(INVALID_KEY_STATE) {} + ~KeyEventInjector(); + bool Read(DeviceData& data) override; + bool SetKey(const DeviceData& data); + uint8_t GetLeftSize() const; +private: + List dataList_; + uint16_t lastKeyId_; + uint16_t lastState_; +}; +} + +#endif // ENABLE_DEBUG +#endif // GRAPHIC_LITE_KEY_EVENT_INJECTOR \ No newline at end of file diff --git a/frameworks/dfx/performance_task.h b/frameworks/dfx/performance_task.h new file mode 100755 index 0000000..cbc62aa --- /dev/null +++ b/frameworks/dfx/performance_task.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef GRAPHIC_LITE_PERFORMANCE_TASK_H +#define GRAPHIC_LITE_PERFORMANCE_TASK_H + +#include "graphic_config.h" +#if ENABLE_DEBUG && ENABLE_DEBUG_PERFORMANCE_TRACE +#include "common/task.h" +#include "graphic_performance.h" + +namespace OHOS { +class PerformanceTask : public Task { +public: + static PerformanceTask* GetInstance() + { + static PerformanceTask instance; + return &instance; + } + + void Init() override + { + Performance::GetInstance()->RegisterSIGUSR1(); + Task::Init(); + } + + void Callback() override + { + Performance::GetInstance()->PrintResult(); + } +private: + PerformanceTask() {} + virtual ~PerformanceTask() {} + PerformanceTask(const PerformanceTask&) = delete; + PerformanceTask& operator=(const PerformanceTask&) = delete; + PerformanceTask(PerformanceTask&&) = delete; + PerformanceTask& operator=(PerformanceTask&&) = delete; +}; +} +#define DEBUG_PERFORMANCE_TASK_INIT() OHOS::PerformanceTask::GetInstance()->Init() +#else +#define DEBUG_PERFORMANCE_TASK_INIT() +#endif +#endif \ No newline at end of file diff --git a/frameworks/dfx/point_event_injector.cpp b/frameworks/dfx/point_event_injector.cpp new file mode 100755 index 0000000..b03375e --- /dev/null +++ b/frameworks/dfx/point_event_injector.cpp @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "dfx/point_event_injector.h" +#if ENABLE_DEBUG +#include "graphic_log.h" + +namespace { +const uint16_t MAX_LIST_SIZE = 500; +} + +namespace OHOS { +PointEventInjector::~PointEventInjector() +{ + ListNode* node = dataList_.Begin(); + while (node != dataList_.End()) { + if (node->data_ != nullptr) { + DeviceData* deleteData = node->data_; + delete deleteData; + } + node = node->next_; + } + dataList_.Clear(); +} + +bool PointEventInjector::SetPointEvent(const DeviceData& data) +{ + if (dataList_.Size() >= MAX_LIST_SIZE) { + GRAPHIC_LOGI("PointEventInjector::SetPointEvent data list is full."); + return false; + } + + DeviceData* tmpData = new DeviceData; + if (tmpData == nullptr) { + GRAPHIC_LOGE("PointEventInjector::SetPointEvent memory allocation failed Err!"); + return false; + } + tmpData->point = data.point; + tmpData->state = data.state; + dataList_.PushBack(tmpData); + return true; +} + +bool PointEventInjector::Read(DeviceData& data) +{ + if (dataList_.Size() > 0) { + lastX_ = dataList_.Front()->point.x; + lastY_ = dataList_.Front()->point.y; + lastState_ = dataList_.Front()->state; + + ListNode* node = dataList_.Begin(); + if (node->data_ != nullptr) { + DeviceData* deleteData = node->data_; + delete deleteData; + } + dataList_.PopFront(); + } + data.point = {lastX_, lastY_}; + data.state = lastState_; +#if ENABLE_WINDOW + if (windowId_ >= 0) { + data.winId = windowId_; + } +#endif + return false; +} + +uint16_t PointEventInjector::GetLeftSize() const +{ + return MAX_LIST_SIZE - dataList_.Size(); +} + +#if ENABLE_WINDOW +void PointEventInjector::SetWindowId(int32_t windowId) +{ + windowId_ = windowId; +} +#endif +} +#endif // ENABLE_DEBUG \ No newline at end of file diff --git a/frameworks/dfx/point_event_injector.h b/frameworks/dfx/point_event_injector.h new file mode 100755 index 0000000..6058455 --- /dev/null +++ b/frameworks/dfx/point_event_injector.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef GRAPHIC_LITE_POINT_EVENT_INJECTOR_H +#define GRAPHIC_LITE_POINT_EVENT_INJECTOR_H + +#include "graphic_config.h" +#if ENABLE_DEBUG +#include "dock/pointer_input_device.h" +#include "list.h" + +namespace OHOS { +class PointEventInjector : public PointerInputDevice { +public: + PointEventInjector() : lastX_(0), lastY_(0), lastState_(0) {} + ~PointEventInjector(); + bool SetPointEvent(const DeviceData& data); + bool Read(DeviceData& data) override; + uint16_t GetLeftSize() const; +#if ENABLE_WINDOW + void SetWindowId(int32_t windowId); +#endif + +private: + List dataList_; + int16_t lastX_; + int16_t lastY_; + uint16_t lastState_; +#if ENABLE_WINDOW + int32_t windowId_ = -1; +#endif +}; +} +#endif // ENABLE_DEBUG +#endif // GRAPHIC_LITE_POINT_EVENT_INJECTOR_H \ No newline at end of file diff --git a/frameworks/dfx/ui_dump_dom_tree.cpp b/frameworks/dfx/ui_dump_dom_tree.cpp new file mode 100755 index 0000000..74d4fb0 --- /dev/null +++ b/frameworks/dfx/ui_dump_dom_tree.cpp @@ -0,0 +1,386 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "dfx/ui_dump_dom_tree.h" + +#if ENABLE_DEBUG +#include "components/root_view.h" +#include "components/ui_view.h" +#include "components/ui_label.h" +#include "components/ui_label_button.h" +#include "components/ui_checkbox.h" +#include "components/ui_toggle_button.h" +#include "components/ui_image_view.h" +#include "components/ui_abstract_progress.h" +#include "components/ui_scroll_view.h" +#include "components/ui_list.h" +#include "components/ui_abstract_clock.h" +#include "components/ui_picker.h" +#include "components/ui_swipe_view.h" +#include "components/ui_time_picker.h" +#include "draw/draw_image.h" +#include "file.h" +#include "graphic_log.h" +#endif // ENABLE_DEBUG +namespace OHOS { +#if ENABLE_DEBUG +void UIDumpDomTree::AddNameField(UIViewType type, cJSON* usr) const +{ + if (usr == nullptr) { + return; + } + + if (type < UI_NUMBER_MAX) { + cJSON_AddStringToObject(usr, "name", VIEW_TYPE_STRING[type]); + } else { + cJSON_AddStringToObject(usr, "name", "UnknownType"); + } +} + +void UIDumpDomTree::AddImageViewSpecialField(const UIView* view, cJSON* usr) const +{ + if ((view == nullptr) || (usr == nullptr)) { + return; + } + const UIImageView* tmpImageView = static_cast(view); + ImageSrcType srcType = tmpImageView->GetSrcType(); + if (srcType == IMG_SRC_FILE) { + cJSON_AddStringToObject(usr, "src", reinterpret_cast(tmpImageView->GetPath())); + } else if (srcType == IMG_SRC_VARIABLE) { + const ImageInfo* imageInfo = reinterpret_cast(tmpImageView->GetImageInfo()); + if ((imageInfo == nullptr) || (imageInfo->userData == nullptr)) { + cJSON_AddStringToObject(usr, "src", ""); + return; + } + uintptr_t userData = reinterpret_cast(imageInfo->userData); + cJSON_AddNumberToObject(usr, "src", static_cast(userData)); + } else { + cJSON_AddStringToObject(usr, "src", ""); + } +} + +void UIDumpDomTree::AddSpecialField(const UIView* view, cJSON* usr) const +{ + if ((view == nullptr) || (usr == nullptr)) { + return; + } + switch (view->GetViewType()) { + case UI_LABEL: + case UI_ARC_LABEL: { + const UILabel* tmpLabel = static_cast(view); + cJSON_AddStringToObject(usr, "text", tmpLabel->GetText()); + tmpLabel = nullptr; + break; + } + case UI_LABEL_BUTTON: { + const UILabelButton* tmpLabelButton = static_cast(view); + cJSON_AddStringToObject(usr, "text", tmpLabelButton->GetText()); + tmpLabelButton = nullptr; + break; + } + case UI_CHECK_BOX: + case UI_RADIO_BUTTON: { + const UICheckBox* tmpCheckBox = static_cast(view); + if (tmpCheckBox->GetState()) { + cJSON_AddStringToObject(usr, "state", "UNSELECTED"); + } else { + cJSON_AddStringToObject(usr, "state", "SELECTED"); + } + tmpCheckBox = nullptr; + break; + } + case UI_TOGGLE_BUTTON: { + const UIToggleButton* tmpToggleButton = static_cast(view); + cJSON_AddBoolToObject(usr, "state", tmpToggleButton->GetState()); + tmpToggleButton = nullptr; + break; + } + case UI_IMAGE_VIEW: { + AddImageViewSpecialField(view, usr); + break; + } + // case below are all progress, thus has same attr. + case UI_BOX_PROGRESS: + case UI_SLIDER: + case UI_CIRCLE_PROGRESS: { + const UIAbstractProgress* tmpAbstractProgress = static_cast(view); + cJSON_AddNumberToObject(usr, "currValue", static_cast(tmpAbstractProgress->GetValue())); + cJSON_AddNumberToObject(usr, "rangeMin", static_cast(tmpAbstractProgress->GetRangeMin())); + cJSON_AddNumberToObject(usr, "rangeMax", static_cast(tmpAbstractProgress->GetRangeMax())); + tmpAbstractProgress = nullptr; + break; + } + case UI_SCROLL_VIEW: { + const UIScrollView* tmpScrollView = static_cast(view); + cJSON_AddBoolToObject(usr, "xScrollable", tmpScrollView->GetHorizontalScrollState()); + cJSON_AddBoolToObject(usr, "yScrollable", tmpScrollView->GetVerticalScrollState()); + tmpScrollView = nullptr; + break; + } + case UI_LIST: { + UIList* tmpList = static_cast(const_cast(view)); + cJSON_AddBoolToObject(usr, "isLoopList", tmpList->GetLoopState()); + UIView* selectView = tmpList->GetSelectView(); + if (selectView != nullptr) { + cJSON_AddNumberToObject(usr, "selectedIndex", static_cast(selectView->GetViewIndex())); + selectView = nullptr; + } + tmpList = nullptr; + break; + } + case UI_DIGITAL_CLOCK: + case UI_ANALOG_CLOCK: { + const UIAbstractClock* tmpAbstractClock = static_cast(view); + cJSON_AddNumberToObject(usr, "currentHour", static_cast(tmpAbstractClock->GetCurrentHour())); + cJSON_AddNumberToObject(usr, "currentMinute", static_cast(tmpAbstractClock->GetCurrentMinute())); + cJSON_AddNumberToObject(usr, "currentSecond", static_cast(tmpAbstractClock->GetCurrentSecond())); + tmpAbstractClock = nullptr; + break; + } + case UI_PICKER: { + const UIPicker* tmpPicker = static_cast(view); + cJSON_AddNumberToObject(usr, "selectedIndex", static_cast(tmpPicker->GetSelected())); + tmpPicker = nullptr; + break; + } + case UI_SWIPE_VIEW: { + const UISwipeView* tmpSwipeView = static_cast(view); + cJSON_AddNumberToObject(usr, "currentIndex", static_cast(tmpSwipeView->GetCurrentPage())); + cJSON_AddNumberToObject(usr, "direction", static_cast(tmpSwipeView->GetDirection())); + tmpSwipeView = nullptr; + break; + } + case UI_TIME_PICKER: { + const UITimePicker* tmpTimePicker = static_cast(view); + cJSON_AddStringToObject(usr, "selectedHour", tmpTimePicker->GetSelectHour()); + cJSON_AddStringToObject(usr, "selectedMinute", tmpTimePicker->GetSelectMinute()); + cJSON_AddStringToObject(usr, "selectedSecond", tmpTimePicker->GetSelectSecond()); + tmpTimePicker = nullptr; + break; + } + default: + break; + } +} + +void UIDumpDomTree::AddCommonField(UIView* view, cJSON* usr) const +{ + if ((view == nullptr) || (usr == nullptr)) { + return; + } + cJSON_AddNumberToObject(usr, "x", static_cast(view->GetOrigRect().GetX())); + cJSON_AddNumberToObject(usr, "y", static_cast(view->GetOrigRect().GetY())); + cJSON_AddNumberToObject(usr, "width", static_cast(view->GetWidth())); + cJSON_AddNumberToObject(usr, "height", static_cast(view->GetHeight())); + cJSON_AddStringToObject(usr, "id", view->GetViewId()); + cJSON_AddBoolToObject(usr, "visible", view->IsVisible()); + cJSON_AddBoolToObject(usr, "touchable", view->IsTouchable()); + cJSON_AddBoolToObject(usr, "draggable", view->IsDraggable()); + cJSON_AddBoolToObject(usr, "onClickListener", (view->GetOnClickListener() != nullptr)); + cJSON_AddBoolToObject(usr, "onDragListener", (view->GetOnDragListener() != nullptr)); + cJSON_AddBoolToObject(usr, "onLongPressListener", (view->GetOnLongPressListener() != nullptr)); +} + +void UIDumpDomTree::OutputDomNode(UIView* view) +{ + if (view == nullptr) { + return; + } + /* Output current view's info into cJSON structure. */ + cJSON* dumpUsr = cJSON_CreateObject(); + if (dumpUsr == nullptr) { + GRAPHIC_LOGE("UIDumpDomTree::OutputDomNode cJSON create object failed Err!\n"); + return; + } + + AddNameField(view->GetViewType(), dumpUsr); + AddCommonField(view, dumpUsr); + AddSpecialField(view, dumpUsr); + + pJson_ = cJSON_Print(dumpUsr); + cJSON_Delete(dumpUsr); +} + +bool UIDumpDomTree::WriteDumpFile() const +{ + unlink(path_); + int32_t fd = open(path_, O_CREAT | O_RDWR, DEFAULT_FILE_PERMISSION); + if (fd < 0) { + GRAPHIC_LOGE("UIDumpDomTree::WriteDumpFile open file failed Err!\n"); + return false; + } + + if (pJson_ == nullptr) { + close(fd); + return false; + } + + uint32_t length = strlen(pJson_); + if (static_cast(write(fd, pJson_, length)) != length) { + GRAPHIC_LOGE("UIDumpDomTree::WriteDumpFile write file failed Err!\n"); + close(fd); + return false; + } + + if (close(fd) < 0) { + return false; + } + return true; +} + +void UIDumpDomTree::OutputDomTree(UIView* view, cJSON* usr) +{ + if (allocErrorFlag_) { + return; + } + + cJSON* dumpUsr = usr; + if (dumpUsr != rootJson_) { + dumpUsr = cJSON_CreateObject(); + if (dumpUsr == nullptr) { + allocErrorFlag_ = true; + GRAPHIC_LOGE("UIDumpDomTree::OutputDomTree cJSON create object failed Err!\n"); + return; + } + /* usr must be a array. */ + cJSON_AddItemToArray(usr, dumpUsr); + } + + AddNameField(view->GetViewType(), dumpUsr); + AddCommonField(view, dumpUsr); + AddSpecialField(view, dumpUsr); + + if (view->IsViewGroup()) { + cJSON* arrayJson = cJSON_CreateArray(); + if (arrayJson == nullptr) { + allocErrorFlag_ = true; + GRAPHIC_LOGE("UIDumpDomTree::OutputDomTree cJSON create object failed Err!\n"); + return; + } + + cJSON_AddItemToObject(dumpUsr, "child", arrayJson); + UIViewGroup* tmpViewGroup = static_cast(view); + UIView* childView = tmpViewGroup->GetChildrenHead(); + while (childView != nullptr) { + OutputDomTree(childView, arrayJson); + childView = childView->GetNextSibling(); + } + } +} + +void UIDumpDomTree::DumpJsonById(UIView* view, const char* id, DumpMode mode) +{ + if (searchFlag_) { + return; + } + + /* Check whether current view is the view we are looking for. */ + if ((view->GetViewId() != nullptr) && !strcmp(view->GetViewId(), id)) { + if (mode == DUMP_NODE) { + /* Find the view with right id, output its info. */ + OutputDomNode(view); + } else if (mode == DUMP_TREE) { + /* Find the view with right id, output its dom tree's info. */ + OutputDomTree(view, rootJson_); + } + /* Set flag to stop the tranversion. */ + searchFlag_ = true; + } else { + /* Look through all childrens of the current viewGroup. */ + if (view->IsViewGroup()) { + UIViewGroup* tmpViewGroup = static_cast(view); + UIView* childView = tmpViewGroup->GetChildrenHead(); + while (childView != nullptr) { + DumpJsonById(childView, id, mode); + childView = childView->GetNextSibling(); + } + } + } +} +#endif // ENABLE_DEBUG + +char* UIDumpDomTree::DumpDomNode(const char* id) +{ +#if ENABLE_DEBUG + if (id == nullptr) { + return nullptr; + } + /* Reset dump info */ + pJson_ = nullptr; + + RootView* rootView = RootView::GetInstance(); + UIView* currView = static_cast(rootView); + /* Search through all views from rootView. */ + DumpJsonById(currView, id, DUMP_NODE); + + /* Reset the search flag and pJson for next search */ + searchFlag_ = false; + return pJson_; +#else + return nullptr; +#endif // ENABLE_DEBUG +} + +bool UIDumpDomTree::DumpDomTree(const char* id, const char* path) +{ +#if ENABLE_DEBUG + path_ = (path == nullptr) ? DEFAULT_DUMP_DOM_TREE_PATH : path; + + RootView* rootView = RootView::GetInstance(); + UIView* currView = static_cast(rootView); + rootJson_ = cJSON_CreateObject(); + if (rootJson_ == nullptr) { + GRAPHIC_LOGE("UIDumpDomTree::DumpDomTree cJSON create object failed Err!\n"); + return false; + } + + if (id == nullptr) { + OutputDomTree(currView, rootJson_); + } else { + DumpJsonById(currView, id, DUMP_TREE); + if (!searchFlag_) { + cJSON_Delete(rootJson_); + rootJson_ = nullptr; + GRAPHIC_LOGI("UIDumpDomTree::DumpDomTree can not find the node \n"); + return false; + } + /* Reset the search flag. */ + searchFlag_ = false; + } + + pJson_ = cJSON_Print(rootJson_); + cJSON_Delete(rootJson_); + rootJson_ = nullptr; + if (pJson_ == nullptr) { + GRAPHIC_LOGE("UIDumpDomTree::DumpDomTree convert cJSON object to string failed Err!\n"); + return false; + } + + if (!WriteDumpFile()) { + cJSON_free(pJson_); + pJson_ = nullptr; + GRAPHIC_LOGE("UIDumpDomTree::DumpDomTree file operation failed Err!\n"); + return false; + } + + cJSON_free(pJson_); + pJson_ = nullptr; + allocErrorFlag_ = false; + return true; +#else + return false; +#endif // ENABLE_DEBUG +} +} diff --git a/frameworks/dfx/ui_screenshot.cpp b/frameworks/dfx/ui_screenshot.cpp new file mode 100755 index 0000000..431533a --- /dev/null +++ b/frameworks/dfx/ui_screenshot.cpp @@ -0,0 +1,167 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "dfx/ui_screenshot.h" + +#if ENABLE_DEBUG +#include "iwindows_manager.h" +#include "color.h" +#include "common/screen.h" +#include "draw/draw_utils.h" +#include "file.h" +#include "graphic_log.h" +#include "image_info.h" +#include "securec.h" + +namespace OHOS { +class UIScreenshotListener : public IWindowsManager::ScreenshotListener { +public: + UIScreenshotListener() : filePath_(nullptr) {} + + virtual ~UIScreenshotListener() + { + if (filePath_ != nullptr) { + UIFree(reinterpret_cast(filePath_)); + filePath_ = nullptr; + } + } + + void OnScreenshotEnd(uint8_t* virAddr, uint32_t width, uint32_t height, + ImagePixelFormat format, uint32_t stride) override + { + if ((virAddr == nullptr) || ((format != IMAGE_PIXEL_FORMAT_ARGB1555) && + (format != IMAGE_PIXEL_FORMAT_ARGB8888))) { + return; + } + + ImageHeader header = {0}; + header.colorMode = ARGB8888; + header.width = width; + header.height = height; + + unlink(filePath_); + int32_t fd = open(filePath_, O_RDWR | O_CREAT, DEFAULT_FILE_PERMISSION); + UIFree(reinterpret_cast(filePath_)); + filePath_ = nullptr; + if (fd < 0) { + GRAPHIC_LOGE("UIScreenshotListener::OnScreenshotEnd open file failed Err!\n"); + return; + } + + if (write(fd, &header, sizeof(ImageHeader)) != sizeof(ImageHeader)) { + GRAPHIC_LOGE("UIScreenshotListener::OnScreenshotEnd write image header failed Err!\n"); + close(fd); + return; + } + + uint32_t row = MAX_MALLOC_SIZE / width; + row = (row == 0) ? 1 : row; + uint32_t size = row * width * sizeof(uint32_t); + uint32_t* argb8888Addr = static_cast(UIMalloc(size)); + if (argb8888Addr == nullptr) { + GRAPHIC_LOGE("UIScreenshotListener::OnScreenshotEnd memory allocation failed Err!"); + close(fd); + return; + } + + while (height >= row) { + WriteBlockToFile(fd, argb8888Addr, virAddr, row, width, format, stride); + height -= row; + } + if (height != 0) { + WriteBlockToFile(fd, argb8888Addr, virAddr, height, width, format, stride); + } + UIFree(reinterpret_cast(argb8888Addr)); + close(fd); + } + + void SetFilePath(char* path) + { + if (filePath_ != nullptr) { + UIFree(reinterpret_cast(filePath_)); + } + filePath_ = path; + } + +private: + static constexpr uint8_t DEFAULT_COLOR_SIZE = 4; + static constexpr uint16_t MAX_MALLOC_SIZE = 2048; // unit: 4 bytes + char* filePath_; + + bool WriteBlockToFile(int32_t fd, uint32_t* buffer, uint8_t*& startAddr, uint32_t row, + uint32_t width, ImagePixelFormat format, uint32_t stride) const + { + uint32_t* argb8888Addr = buffer; + for (uint32_t r = 0; r < row; ++r) { + if (format == IMAGE_PIXEL_FORMAT_ARGB1555) { + uint16_t* temp = reinterpret_cast(startAddr); + for (uint32_t i = 0; i < width; ++i) { + buffer[i] = PixelFormatUtils::ARGB1555ToARGB8888(*temp++); + } + } else if (format == IMAGE_PIXEL_FORMAT_ARGB8888) { + if (memcpy_s(buffer, width * DEFAULT_COLOR_SIZE, startAddr, width * DEFAULT_COLOR_SIZE) != EOK) { + GRAPHIC_LOGE("memcpy_s error!"); + } + } + startAddr += stride; + buffer += width; + } + + uint32_t blockSize = row * width * sizeof(uint32_t); + if (static_cast(write(fd, argb8888Addr, blockSize)) != blockSize) { + GRAPHIC_LOGE("UIScreenshotListener::WriteBlockToFile wrong amount of written data Err!"); + return false; + } + return true; + } +}; + +UIScreenshot::~UIScreenshot() +{ + if (screenshotListener_ != nullptr) { + delete screenshotListener_; + screenshotListener_ = nullptr; + } +} + +bool UIScreenshot::ScreenshotToFile(const char* path) +{ + if (screenshotListener_ == nullptr) { + screenshotListener_ = new UIScreenshotListener(); + if (screenshotListener_ == nullptr) { + GRAPHIC_LOGE("UIScreenshot::ScreenshotToFile register screenshot listener failed Err!\n"); + return false; + } + IWindowsManager::GetInstance()->SetScreenshotListener(screenshotListener_); + } + + const char* srcPath = (path == nullptr) ? DEFAULT_SCREENSHOT_PATH : path; + uint32_t pathLength = strlen(srcPath); + char* destPath = static_cast(UIMalloc(pathLength + 1)); + if (destPath == nullptr) { + return false; + } + + if (memcpy_s(destPath, pathLength + 1, srcPath, pathLength) != EOK) { + UIFree(reinterpret_cast(destPath)); + return false; + } + destPath[pathLength] = '\0'; + screenshotListener_->SetFilePath(destPath); + IWindowsManager::GetInstance()->Screenshot(); + return true; +} +} // namespace OHOS +#endif // ENABLE_DEBUG \ No newline at end of file diff --git a/frameworks/dock/input_device.cpp b/frameworks/dock/input_device.cpp new file mode 100755 index 0000000..a6c4c5a --- /dev/null +++ b/frameworks/dock/input_device.cpp @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "dock/input_device.h" + +namespace OHOS { +void InputDevice::ProcessEvent() +{ + DeviceData data; + bool moreToRead = false; + do { + moreToRead = Read(data); + DispatchEvent(data); + } while (moreToRead); +} +} // namespace OHOS diff --git a/frameworks/dock/input_device.h b/frameworks/dock/input_device.h new file mode 100755 index 0000000..fcc0326 --- /dev/null +++ b/frameworks/dock/input_device.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef GRAPHIC_LITE_INPUT_DEVICE_H +#define GRAPHIC_LITE_INPUT_DEVICE_H + +#include "input_event_info.h" +#include "heap_base.h" + +namespace OHOS { +/** + * @brief Input device base class. + */ +class InputDevice : public HeapBase { +public: + InputDevice() : rawDataState_(STATE_RELEASE) {} + virtual ~InputDevice() {} + + /** + * @brief Process event from input device driver. + */ + void ProcessEvent(); + + /** + * @brief Read data from hardware.User should override this to set data + * + * @param [out] input device data. + * + * @returns no more data to read if true. + */ + virtual bool Read(DeviceData& data) = 0; + + constexpr static uint8_t STATE_RELEASE = 0; + constexpr static uint8_t STATE_PRESS = 1; + +protected: + uint16_t rawDataState_; + + /** + * @brief Dispatch event to ui component. + * @param [in] data data received from hardware + */ + virtual void DispatchEvent(const DeviceData& data) = 0; +}; +} // namespace OHOS +#endif // GRAPHIC_LITE_INPUT_DEVICE_H diff --git a/frameworks/dock/key_input_device.cpp b/frameworks/dock/key_input_device.cpp new file mode 100755 index 0000000..79ee9dc --- /dev/null +++ b/frameworks/dock/key_input_device.cpp @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "dock/key_input_device.h" +#include "components/root_view.h" +#include "graphic_math.h" +#include "hal_tick.h" + +namespace OHOS { +void KeyInputDevice::DispatchEvent(const DeviceData& data) +{ + if (data.state != INVALID_KEY_STATE) { + KeyEvent event(data.keyId, data.state); + RootView::GetInstance()->OnKeyEvent(event); + } +} +} // namespace OHOS diff --git a/frameworks/dock/key_input_device.h b/frameworks/dock/key_input_device.h new file mode 100755 index 0000000..46ed95e --- /dev/null +++ b/frameworks/dock/key_input_device.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef GRAPHIC_LITE_KEY_INPUT_DEVICE_H +#define GRAPHIC_LITE_KEY_INPUT_DEVICE_H + +#include "dock/input_device.h" + +namespace OHOS { +/** @brief A key input device. */ +class KeyInputDevice : public InputDevice { +public: + /** + * @brief Constructor + * + * @param [in] read If non-null, the read. + * @param [in] userData If non-null, information describing the user. + */ + KeyInputDevice() {} + /** @brief Destructor */ + virtual ~KeyInputDevice() {} + +private: + void DispatchEvent(const DeviceData& data) override; +}; +} // namespace OHOS +#endif // UI_INCLUDE_CORE_PHYKEY_INPUT_DEVICE_H diff --git a/frameworks/dock/ohos/ohos_input_device.cpp b/frameworks/dock/ohos/ohos_input_device.cpp new file mode 100755 index 0000000..76832d7 --- /dev/null +++ b/frameworks/dock/ohos/ohos_input_device.cpp @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "dock/ohos/ohos_input_device.h" +#include "input_event_info.h" +#include "iwindows_manager.h" + +namespace OHOS { +bool OHOSInputDevice::Read(DeviceData& data) +{ + IWindowsManager::GetInstance()->GetEventData(&data); + return false; +} +} diff --git a/frameworks/dock/ohos/ohos_input_device.h b/frameworks/dock/ohos/ohos_input_device.h new file mode 100755 index 0000000..85428e1 --- /dev/null +++ b/frameworks/dock/ohos/ohos_input_device.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef GRAPHIC_LITE_OHOS_INPUT_DEVICE_H +#define GRAPHIC_LITE_OHOS_INPUT_DEVICE_H + +#include "dock/pointer_input_device.h" + +namespace OHOS { +class OHOSInputDevice : public PointerInputDevice { +public: + OHOSInputDevice() {} + + virtual ~OHOSInputDevice() {} + + bool Read(DeviceData& data) override; +}; +} +#endif diff --git a/frameworks/dock/pointer_input_device.cpp b/frameworks/dock/pointer_input_device.cpp new file mode 100755 index 0000000..df90071 --- /dev/null +++ b/frameworks/dock/pointer_input_device.cpp @@ -0,0 +1,324 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "dock/pointer_input_device.h" + +#include "components/root_view.h" +#include "core/render_manager.h" +#if ENABLE_AOD +#include "events/aod_callback.h" +#endif +#include "graphic_log.h" +#include "graphic_math.h" +#if ENABLE_WINDOW +#include "window/window.h" +#endif + +namespace OHOS { +void PointerInputDevice::DispatchEvent(const DeviceData& data) +{ + curPos_ = data.point; +#if ENABLE_WINDOW + Window* window = RenderManager::GetInstance().GetWindowById(data.winId); + if (window == nullptr) { + return; + } + curPos_.x = curPos_.x - window->GetRect().GetLeft(); + curPos_.y = curPos_.y - window->GetRect().GetTop(); + UIViewGroup* rootView = window->GetRootView(); + if (rootView == nullptr) { + return; + } +#else + UIViewGroup* rootView = RootView::GetInstance(); +#endif + // invalid touchable and draggable view will be reset to nullptr + if ((touchableView_ != nullptr) && !RootView::FindSubView(*rootView, touchableView_)) { + touchableView_ = nullptr; + lastPos_ = curPos_; + } + if ((draggableView_ != nullptr) && !RootView::FindSubView(*rootView, draggableView_)) { + draggableView_ = nullptr; + lastPos_ = curPos_; + dragLastPos_ = curPos_; + dragLen_ = { 0, 0 }; + dragStep_ = { 0, 0 }; + isDragging_ = false; + } + + if (data.state == STATE_PRESS) { + DispatchPressEvent(rootView); + } else { + DispatchReleaseEvent(rootView); + } + dragLastPos_ = lastPos_; + lastPos_ = curPos_; +} + +void PointerInputDevice::DispatchPressEvent(UIViewGroup* rootView) +{ + if (rootView == nullptr) { + return; + } + // first time to press + if (!pressState_) { + rootView->GetTargetView(curPos_, &touchableView_, &targetView_); + if (touchableView_ == nullptr) { + GRAPHIC_LOGD("PointerInputDevice::DispatchPressEvent cannot find target view!\n"); + return; + } + draggableView_ = GetDraggableView(touchableView_); + pressState_ = true; + pressTimeStamp_ = HALTick::GetInstance().GetTime(); + lastPos_ = curPos_; + dragLastPos_ = lastPos_; + return; + } + uint32_t elapse = HALTick::GetInstance().GetElapseTime(pressTimeStamp_); + DispatchDragStartEvent(); + DispatchDragEvent(); + if (!isDragging_ && (touchableView_ != nullptr) && !cancelSent_) { + UIView* tempView = nullptr; + rootView->GetTargetView(curPos_, &tempView, &targetView_); + if (tempView != touchableView_) { + DispatchCancelEvent(); + } else { + if (!pressSent_ && (elapse > INDEV_PRESS_TIME_IN_DRAG)) { + PressEvent evt(curPos_); + UIView* parent = touchableView_->GetParent(); + if (!touchableView_->OnPressEvent(evt)) { + while (parent != nullptr) { + PressEvent evtParent(curPos_); + if (parent->UIView::OnPressEvent(evtParent)) { + break; + } + parent = parent->GetParent(); + } + } + pressSent_ = true; + } + DispatchLongPressEvent(elapse); + } + } +} + +bool PointerInputDevice::ProcessReleaseEvent() +{ + UIView* parent = touchableView_->GetParent(); + // reissue press event. + if (!pressSent_) { + PressEvent evtPress(curPos_); + if (!touchableView_->OnPressEvent(evtPress)) { + while (parent != nullptr) { + PressEvent evtPressParent(curPos_); + if (parent->UIView::OnPressEvent(evtPressParent)) { + break; + } + parent = parent->GetParent(); + } + } + pressSent_ = true; + return false; + } else { + ReleaseEvent evtRelease(curPos_); + if (!touchableView_->OnReleaseEvent(evtRelease)) { + while (parent != nullptr) { + ReleaseEvent evtReleaseParent(curPos_); + if (parent->UIView::OnReleaseEvent(evtReleaseParent)) { + break; + } + parent = parent->GetParent(); + } + } + + if (pressSent_ && needClick_) { + ClickEvent evt(curPos_); + parent = touchableView_->GetParent(); + if (!touchableView_->OnClickEvent(evt)) { + while (parent != nullptr) { +#if ENABLE_AOD + OnClickEventHappen(parent); +#endif + ClickEvent evtParent(curPos_); + if (parent->UIView::OnClickEvent(evtParent)) { + break; + } + parent = parent->GetParent(); + } + } +#if ENABLE_AOD + OnClickEventHappen(*touchableView_); +#endif + } + } + return true; +} + +void PointerInputDevice::DispatchReleaseEvent(UIViewGroup* rootView) +{ + if (!pressState_ || (rootView == nullptr)) { + return; + } + + DispatchDragStartEvent(); + DispatchDragEndEvent(); + if (!isDragging_ && (touchableView_ != nullptr) && !cancelSent_) { + UIView* tempView = nullptr; + rootView->GetTargetView(curPos_, &tempView, &targetView_); + if (tempView != touchableView_) { + DispatchCancelEvent(); + } else { + if (!ProcessReleaseEvent()) { + return; + } + } + } + isDragging_ = false; + pressState_ = false; + pressSent_ = false; + cancelSent_ = false; + longPressSent_ = false; + needClick_ = true; + touchableView_ = nullptr; +} + +void PointerInputDevice::DispatchDragStartEvent() +{ + if (draggableView_ == nullptr) { + return; + } + dragStep_.x = curPos_.x - lastPos_.x; + dragStep_.y = curPos_.y - lastPos_.y; + dragLen_.x += dragStep_.x; + dragLen_.y += dragStep_.y; + if (!isDragging_) { + if ((MATH_ABS(dragLen_.x) >= INDEV_DRAG_LIMIT) || (MATH_ABS(dragLen_.y) >= INDEV_DRAG_LIMIT)) { + if ((touchableView_ != nullptr) && !cancelSent_) { + DispatchCancelEvent(); + } + // Send Drag Begin Event. + DragEvent evt(curPos_, lastPos_, dragLen_); + UIView* parent = draggableView_->GetParent(); + if (!draggableView_->OnDragStartEvent(evt)) { + while (parent != nullptr) { + DragEvent evtParent(curPos_, lastPos_, dragLen_); + if (parent->UIView::OnDragStartEvent(evtParent)) { + break; + } + parent = parent->GetParent(); + } + } + dragLastPos_ = lastPos_; + isDragging_ = true; + } + } +} + +void PointerInputDevice::DispatchDragEvent() +{ + if ((draggableView_ == nullptr) || !isDragging_) { + return; + } + if ((dragStep_.x != 0) || (dragStep_.y != 0)) { + DragEvent evt(curPos_, lastPos_, dragLen_); + UIView* parent = draggableView_->GetParent(); + if (!draggableView_->OnDragEvent(evt)) { + while (parent != nullptr) { + DragEvent evtParent(curPos_, lastPos_, dragLen_); + if (parent->UIView::OnDragEvent(evtParent)) { + break; + } + parent = parent->GetParent(); + } + } + } +} + +void PointerInputDevice::DispatchDragEndEvent() +{ + if (draggableView_ == nullptr) { + return; + } + + if (isDragging_) { + DragEvent evt(curPos_, lastPos_, dragLen_); + UIView* parent = draggableView_->GetParent(); + evt.SetPreLastPoint(dragLastPos_); + if (!draggableView_->OnDragEndEvent(evt)) { + while (parent != nullptr) { + DragEvent evtParent(curPos_, lastPos_, dragLen_); + if (parent->UIView::OnDragEndEvent(evtParent)) { + break; + } + parent = parent->GetParent(); + } + } +#if ENABLE_AOD + OnDragEndEventHappen(*draggableView_); +#endif + } + dragLen_ = { 0, 0 }; + dragStep_ = { 0, 0 }; + draggableView_ = nullptr; +} + +void PointerInputDevice::DispatchLongPressEvent(uint32_t elapse) +{ + if (!longPressSent_ && (elapse > INDEV_LONG_PRESS_TIME)) { + longPressSent_ = true; + LongPressEvent evt(curPos_, pressTimeStamp_); + bool isConsumed = touchableView_->OnLongPressEvent(evt); + if (touchableView_->GetOnLongPressListener() != nullptr) { + needClick_ = false; + } + UIView* parent = touchableView_->GetParent(); +#if ENABLE_AOD + OnLongPressEventHappen(*touchableView_); +#endif + if (!isConsumed) { + while (parent != nullptr) { + LongPressEvent evtParent(curPos_, pressTimeStamp_); + isConsumed = parent->UIView::OnLongPressEvent(evtParent); + if (needClick_ && (parent->GetOnLongPressListener() != nullptr)) { + needClick_ = false; + } +#if ENABLE_AOD + OnLongPressEventHappen(*parent); +#endif + if (isConsumed) { + break; + } + parent = parent->GetParent(); + } + } + } +} + +void PointerInputDevice::DispatchCancelEvent() +{ + CancelEvent evt(lastPos_); + UIView* parent = touchableView_->GetParent(); + if (!touchableView_->OnCancelEvent(evt)) { + while (parent != nullptr) { + CancelEvent evtParent(lastPos_); + if (parent->UIView::OnCancelEvent(evtParent)) { + break; + } + parent = parent->GetParent(); + } + } + cancelSent_ = true; +} +} // namespace OHOS diff --git a/frameworks/dock/pointer_input_device.h b/frameworks/dock/pointer_input_device.h new file mode 100755 index 0000000..295fb93 --- /dev/null +++ b/frameworks/dock/pointer_input_device.h @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef GRAPHIC_LITE_POINTER_INPUT_DEVICE_H +#define GRAPHIC_LITE_POINTER_INPUT_DEVICE_H + +#include "hal_tick.h" +#include "dock/input_device.h" +#include "components/ui_view_group.h" + +namespace OHOS { +/** @brief A pointer input device. */ +class PointerInputDevice : public InputDevice { +public: + PointerInputDevice() + : touchableView_(nullptr), draggableView_(nullptr), targetView_(nullptr), lastPos_({0, 0}), + dragLastPos_({0, 0}), curPos_({ 0, 0 }), dragStep_({ 0, 0 }), dragLen_({ 0, 0 }), pressState_(false), + pressSent_(false), longPressSent_(false), cancelSent_(false), isDragging_(false), needClick_(true), + pressTimeStamp_(0) + {} + virtual ~PointerInputDevice() {} + +protected: + void DispatchEvent(const DeviceData& data) override; + +private: + UIView* touchableView_; + UIView* draggableView_; + UIView* targetView_; + Point lastPos_; + Point dragLastPos_; + Point curPos_; + Point dragStep_; + Point dragLen_; + bool pressState_; + bool pressSent_; + bool longPressSent_; + bool cancelSent_; + bool isDragging_; + bool needClick_; + uint32_t pressTimeStamp_; + + void DispatchPressEvent(UIViewGroup* rootView); + void DispatchReleaseEvent(UIViewGroup* rootView); + void DispatchDragStartEvent(); + void DispatchDragEndEvent(); + void DispatchDragEvent(); + void DispatchLongPressEvent(uint32_t elapse); + void DispatchCancelEvent(); + bool ProcessReleaseEvent(); + UIView* GetDraggableView(UIView* targetView) const + { + UIView* tempView = targetView; + while ((tempView != nullptr) && tempView->IsDragParentInstead()) { + tempView = tempView->GetParent(); + } + if ((tempView == nullptr) || !tempView->IsDraggable()) { + return nullptr; + } + return tempView; + } +}; +}; // namespace OHOS +#endif // GRAPHIC_LITE_POINTER_INPUT_DEVICE_H diff --git a/frameworks/dock/rotate_input_device.cpp b/frameworks/dock/rotate_input_device.cpp new file mode 100755 index 0000000..6322572 --- /dev/null +++ b/frameworks/dock/rotate_input_device.cpp @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "dock/rotate_input_device.h" +#include "dock/focus_manager.h" + +#if ENABLE_ROTATE_INPUT +namespace OHOS { +static int8_t g_rotateCtrl = INT8_MIN; +void RotateInputDevice::DispatchEvent(const DeviceData& data) +{ + UIView *view_ = FocusManager::GetInstance()->GetFocusedView(); + if (view_ == nullptr) { + return; + } else if (g_rotateCtrl == INT8_MIN) { + g_rotateCtrl = INT8_MAX; + return; + } else if (data.rotate == 0 && g_rotateCtrl == NULL) { + view_->OnRotateEvent(0); + g_rotateCtrl = INT8_MAX; + return; + } else if (data.rotate == 0) { + return; + } else { + g_rotateCtrl = data.rotate; + view_->OnRotateEvent(g_rotateCtrl); + g_rotateCtrl = NULL; + } +} +} // namespace OHOS +#endif diff --git a/frameworks/dock/screen_device.h b/frameworks/dock/screen_device.h new file mode 100755 index 0000000..a43db8b --- /dev/null +++ b/frameworks/dock/screen_device.h @@ -0,0 +1,202 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef GRAPHIC_LITE_SCREEN_DEVICE_H +#define GRAPHIC_LITE_SCREEN_DEVICE_H + +#include "color.h" +#include "graphic_semaphore.h" +#include "graphic_assert.h" +#include "rect.h" +#if ENABLE_WINDOW +#include "pixel_format_utils.h" +#endif + +namespace OHOS { +#if ENABLE_WINDOW +struct AllocationInfo { + uint8_t* virAddr; + uint8_t* phyAddr; + uint16_t width; + uint16_t height; + uint32_t stride; + ImagePixelFormat pixelFormat; +}; +#endif + +struct TransformOption { + TransformAlgorithm algorithm; +}; + +/** @brief A semaphore for display buffer flushing. */ +class FlushSem : public HeapBase { +public: + /** + * Constructor + * + * @param [in] isFlushing (Optional) True if is flushing, false if not. + */ + FlushSem(bool isFlushing = false) : sem_(1, 1), isFlushing_(isFlushing) {} + + /** + * @brief Destructor + */ + virtual ~FlushSem() {} + + /** Notifies the buffer is flushing end */ + void Notify() + { + isFlushing_ = false; + sem_.Notify(); + } + + /** Waits the buffer is flushing */ + void Wait() + { + while (isFlushing_) { + sem_.Wait(); + } + } + + /** set the flag as flashing */ + void Flushing() + { + isFlushing_ = true; + } + +private: + GraphicSemaphore sem_; + bool isFlushing_; +}; + +/** @brief A display device. */ +class ScreenDevice : public HeapBase { +public: + /** + * @brief Constructor + */ + ScreenDevice() {} + + /** + * @brief Destructor + */ + virtual ~ScreenDevice() {} + + virtual void Flush(int16_t x1, int16_t y1, int16_t x2, int16_t y2, const uint8_t* buffer, ColorMode mode) {} + + virtual void Fill(int16_t x1, int16_t y1, int16_t x2, int16_t y2, const ColorType& color) {} + + /** + * @brief Hardware accelerated filling interface implemented by the product platform + * @param fillArea Indicates the area to be filled + * @param color Indicates the color to be filled + * @param opa Indicates the transparency + * @param dst Indicates the start address of destination memory + * @param dstStride Indicates the number of bytes in a single row of destination memory + * @param dstColorMode Indicates the color format of destination memory + * @return Return true on success, false on failure + * @since 5.0 + * @version 3.0 + */ + virtual bool HardwareFill(const Rect& fillArea, + uint32_t color, + OpacityType opa, + uint8_t* dst, + uint32_t dstStride, + ColorMode dstColorMode) + { + return false; + } + + /** + * @brief Hardware accelerated blending interface implemented by the product platform + * @param src Indicates the start address of source memory + * @param srcRect Indicates the area of ​​the source memory for color blending + * @param srcStride Indicates the number of bytes in a single row of source memory + * @param srcLineNumber Indicates the number of source memory rows + * @param srcColorMode Indicates the source memory color format + * @param color 32-bit XRGB8888 value + * (valid when the source memory is in a format with only alph information such as A1) + * @param opa Indicates the transparency + * @param dst Indicates the start address of destination memory + * @param dstStride Indicates the number of bytes in a single row of destination memory + * @param dstColorMode Indicates the color format of destination memory + * @param x The x coordinate of the upper left vertex of the destination memory for color blending + * @param y The y coordinate of the upper left vertex of the destination memory for color blending + * @return Return true on success, false on failure + * @since 5.0 + * @version 3.0 + */ + virtual bool HardwareBlend(const uint8_t* src, + const Rect& srcRect, + uint32_t srcStride, + uint32_t srcLineNumber, + ColorMode srcColorMode, + uint32_t color, + OpacityType opa, + uint8_t* dst, + uint32_t dstStride, + ColorMode dstColorMode, + uint32_t x, + uint32_t y) + { + return false; + } + + /** + * @brief Hardware accelerated transformation interface implemented by the product platform + * @param src Indicates the start address of the source image + * @param srcColorMode Indicates the color format of the source image + * @param srcRect Indicates the position of the source image in the destination memory and its width and height + * @param transformMatrix Indicates the transformation matrix + * @param opa Indicates the transparency + * @param color 32-bit XRGB8888 value + * (valid when the source memory is in a format with only alph information such as A1) + * @param mask Indicates the masking rectangle, and the content beyond the rectangle is not drawn + * @param dst Indicates the start address of destination memory + * @param dstStride Indicates the number of bytes in a single row of destination memory + * @param dstColorMode Indicates the color format of destination memory + * @param option Indicates the optional setting items for transformation operation + * @return Return true on success, false on failure + * @since 5.0 + * @version 3.0 + */ + virtual bool HardwareTransform(const uint8_t* src, + ColorMode srcColorMode, + const Rect& srcRect, + const Matrix3& transformMatrix, + OpacityType opa, + uint32_t color, + const Rect& mask, + uint8_t* dst, + uint32_t dstStride, + ColorMode dstColorMode, + const TransformOption& option) + { + return false; + } + + virtual void SnapShot(uint32_t len, + bool justCopy, + uint8_t* dest, + const Rect& rect, + bool justRender) + { + } + + virtual void RenderFinish() {} +}; +} // namespace OHOS +#endif // GRAPHIC_LITE_SCREEN_DEVICE_H \ No newline at end of file diff --git a/frameworks/dock/screen_device_proxy.h b/frameworks/dock/screen_device_proxy.h new file mode 100755 index 0000000..01f5452 --- /dev/null +++ b/frameworks/dock/screen_device_proxy.h @@ -0,0 +1,232 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef GRAPHIC_LITE_SCREEN_DEVICE_PROXY_H +#define GRAPHIC_LITE_SCREEN_DEVICE_PROXY_H + +#include "color.h" +#include "dock/screen_device.h" +#include "graphic_assert.h" +#include "graphic_semaphore.h" +#include "image_info.h" +#include "rect.h" +#include "transform.h" +#if ENABLE_WINDOW +#include "surface.h" +#endif + +namespace OHOS { +/** @brief A display device proxy */ +class ScreenDeviceProxy : public HeapBase { +public: + static ScreenDeviceProxy* GetInstance() + { + static ScreenDeviceProxy instance; + return &instance; + } + + void SetDevice(ScreenDevice* device) + { + device_ = device; + } + + void Flush(); + + void OnFlushReady(); + + void OnRenderFinish(); + + bool HardwareFill(const Rect& fillArea, + uint32_t color, + OpacityType opa, + uint8_t* dst, + uint32_t dstStride, + ColorMode dstColorMode) + { + if (device_ != nullptr) { + return device_->HardwareFill(fillArea, color, opa, dst, dstStride, dstColorMode); + } + return false; + } + + bool HardwareBlend(const uint8_t* src, + const Rect& srcRect, + uint32_t srcStride, + uint32_t srcLineNumber, + ColorMode srcColorMode, + uint32_t color, + OpacityType opa, + uint8_t* dst, + uint32_t dstStride, + ColorMode dstColorMode, + uint32_t x, + uint32_t y) + { + if (device_ != nullptr) { + return device_->HardwareBlend(src, srcRect, srcStride, srcLineNumber, srcColorMode, color, opa, dst, + dstStride, dstColorMode, x, y); + } + return false; + } + + bool HardwareTransform(const uint8_t* src, + ColorMode srcColorMode, + const Rect& srcRect, + const Matrix3& transformMatrix, + OpacityType opa, + uint32_t color, + const Rect& mask, + uint8_t* dst, + uint32_t dstStride, + ColorMode dstColorMode, + const TransformOption& option) + { + if (device_ != nullptr) { + return device_->HardwareTransform(src, srcColorMode, srcRect, transformMatrix, opa, color, mask, dst, + dstStride, dstColorMode, option); + } + return false; + } + + void SnapShot(uint32_t len, bool justCopy, uint8_t* dest, const Rect& rect, bool justRender) + { + if (device_ != nullptr) { + device_->SnapShot(len, justCopy, dest, rect, justRender); + } + } + +#if ENABLE_FRAME_BUFFER + void SetFramebuffer(uint8_t* addr, ColorMode mode, uint16_t width) + { + frameBufferAddr_ = addr; + frameBufferWidth_ = width; + frameBufferMode_ = mode; + } +#endif + + void SetAnimatorbuffer(uint8_t* addr, ColorMode mode, uint16_t width) + { + animatorBufferAddr_ = addr; + animatorBufferWidth_ = width; + animatorBufferMode_ = mode; + } + + void SetAnimatorbufferWidth(uint16_t width) + { + animatorBufferWidth_ = width; + } + + void EnableAnimatorBuffer(bool status) + { + useAnimatorBuff_ = status; + } + + void SetAnimatorRect(const Rect& rect); + + void SetAnimatorTransMap(TransformMap& transMap) + { + transMap_ = transMap; + } + + void DrawAnimatorBuffer(const Rect& invalidatedArea); + + bool GetAnimatorBufferStatus() + { + return useAnimatorBuff_; + } + +#if ENABLE_WINDOW + AllocationInfo& GetAllocationInfo() + { + return gfxAlloc_; + } +#endif + + uint16_t GetBufferWidth() const + { + if (useAnimatorBuff_) { + return animatorBufferWidth_; + } +#if ENABLE_FRAME_BUFFER + return frameBufferWidth_; +#elif ENABLE_WINDOW + return gfxAlloc_.stride / sizeof(ColorType); +#else + return bufferRect_.GetWidth(); +#endif + } + + Rect& GetBufferRect() + { + return bufferRect_; + } + + void SetScreenSize(uint16_t width, uint16_t height); + + uint16_t GetScreenWidth() const + { + return width_; + } + + uint16_t GetScreenHeight() const + { + return height_; + } + + uint32_t GetScreenArea() const + { + return width_ * height_; + } + + uint8_t* GetBuffer(); + + ColorMode GetBufferMode(); + +private: + ScreenDeviceProxy() {} + virtual ~ScreenDeviceProxy() {} + + ScreenDeviceProxy(const ScreenDeviceProxy&) = delete; + ScreenDeviceProxy& operator=(const ScreenDeviceProxy&) = delete; + ScreenDeviceProxy(ScreenDeviceProxy&&) = delete; + ScreenDeviceProxy& operator=(ScreenDeviceProxy&&) = delete; + + ScreenDevice* device_ = nullptr; + FlushSem flush_ = FlushSem(false); + uint16_t width_ = HORIZONTAL_RESOLUTION; + uint16_t height_ = VERTICAL_RESOLUTION; + uint8_t* buffer_ = nullptr; + Rect bufferRect_; + +#if ENABLE_FRAME_BUFFER + uint8_t* frameBufferAddr_ = nullptr; + uint16_t frameBufferWidth_ = 0; + ColorMode frameBufferMode_ = ARGB8888; +#endif + + uint8_t* animatorBufferAddr_ = nullptr; + uint16_t animatorBufferWidth_ = 0; + ColorMode animatorBufferMode_ = ARGB8888; + Rect curViewRect_; + TransformMap transMap_; + bool useAnimatorBuff_ = false; + ImageInfo animatorImageInfo_ = {{0}}; + +#if ENABLE_WINDOW + AllocationInfo gfxAlloc_ = {0}; +#endif +}; +} // namespace OHOS +#endif // GRAPHIC_LITE_SCREEN_DEVICE_PROXY_H diff --git a/frameworks/dock/virtual_input_device.cpp b/frameworks/dock/virtual_input_device.cpp new file mode 100755 index 0000000..710c4b0 --- /dev/null +++ b/frameworks/dock/virtual_input_device.cpp @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "dock/virtual_input_device.h" +#include "components/root_view.h" +#include "events/virtual_device_event.h" + +#if USE_VIRTUAL_DEVICE +namespace OHOS { +void VirtualInputDevice::DispatchEvent(const DeviceData& data) +{ + if (data.state != INVALID_VIRTUAL_INPUT_STATE) { + VirtualDeviceEvent event(data.type, data.state); + RootView::GetInstance()->OnVirtualDeviceEvent(event); + } +} +} // namespace OHOS +#endif diff --git a/frameworks/dock/virtual_input_device.h b/frameworks/dock/virtual_input_device.h new file mode 100755 index 0000000..060e73d --- /dev/null +++ b/frameworks/dock/virtual_input_device.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef GRAPHIC_LITE_VIRTUAL_INPUT_DEVICE_H +#define GRAPHIC_LITE_VIRTUAL_INPUT_DEVICE_H + +#include "dock/input_device.h" +#include "graphic_config.h" + +#if USE_VIRTUAL_DEVICE +namespace OHOS { +/** @brief virtual input device. */ +class VirtualInputDevice : public InputDevice { +public: + /** @brief Constructor */ + VirtualInputDevice() {} + + /** @brief Destructor */ + virtual ~VirtualInputDevice() {} + +private: + void DispatchEvent(const DeviceData& data) override; + + VirtualInputDevice(const VirtualInputDevice&) = delete; + VirtualInputDevice& operator=(const VirtualInputDevice&) = delete; + VirtualInputDevice(VirtualInputDevice&&) = delete; + VirtualInputDevice& operator=(VirtualInputDevice&&) = delete; +}; +} // namespace OHOS +#endif +#endif // GRAPHIC_LITE_VIRTUAL_INPUT_DEVICE_H diff --git a/frameworks/draw/draw_arc.cpp b/frameworks/draw/draw_arc.cpp new file mode 100755 index 0000000..31ceaf3 --- /dev/null +++ b/frameworks/draw/draw_arc.cpp @@ -0,0 +1,490 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "draw/draw_arc.h" +#include "common/image.h" +#include "graphic_math.h" + +namespace OHOS { +#define IS_IN_DEGREERANE(d, s, e) ((s) <= (e)) ? (((d) >= (s)) && ((d) <= (e))) : (((d) >= (s)) || ((d) <= (e))) + +void DrawArc::DrawImg(const Point& imgPos, + Rect& area, + const Rect& invalidatedArea, + const Style& style, + uint8_t opaScale, + const Image* image) +{ + if (image == nullptr) { + return; + } + ImageHeader header = {0}; + image->GetHeader(header); + + Rect cordsTmp; + cordsTmp.SetPosition(imgPos.x, imgPos.y); + cordsTmp.SetHeight(header.height); + cordsTmp.SetWidth(header.width); + if (area.Intersect(area, invalidatedArea)) { + image->DrawImage(cordsTmp, area, style, opaScale); + } +} + +void DrawArc::DrawVerLine(const Point& begin, + const Point& imgPos, + const Rect& mask, + int16_t len, + const Style& style, + uint8_t opaScale, + const Image* image) +{ + Rect rect(begin.x, begin.y, begin.x, begin.y + len); + if ((image != nullptr) && (image->GetSrcType() != IMG_SRC_UNKNOWN)) { + DrawImg(imgPos, rect, mask, style, opaScale, image); + } else { + DrawUtils::GetInstance()->DrawColorArea(rect, mask, style.lineColor_, opaScale); + } +} + +void DrawArc::DrawHorLine(const Point& begin, + const Point& imgPos, + const Rect& mask, + int16_t len, + const Style& style, + uint8_t opaScale, + const Image* image) +{ + if ((image != nullptr) && (image->GetSrcType() != IMG_SRC_UNKNOWN)) { + Rect rect(begin.x, begin.y, begin.x + len, begin.y); + DrawImg(imgPos, rect, mask, style, opaScale, image); + } else { + if (len == 0) { + DrawUtils::GetInstance()->DrawPixel(begin.x, begin.y, mask, style.lineColor_, opaScale); + } else { + Rect rect(begin.x, begin.y, begin.x + len, begin.y); + DrawUtils::GetInstance()->DrawColorArea(rect, mask, style.lineColor_, opaScale); + } + } +} + +int16_t DrawArc::GetDrawAngle(int16_t angle) +{ + if (angle < 0) { + angle = (angle % CIRCLE_IN_DEGREE) + CIRCLE_IN_DEGREE; + } else if (angle > CIRCLE_IN_DEGREE) { + angle = angle % CIRCLE_IN_DEGREE; + } + return angle; +} + +void DrawArc::GetDrawRange(int16_t& start, int16_t& end) +{ + int16_t tempAngle = GetDrawAngle(start); + if (start == end) { + start = tempAngle; + end = tempAngle; + } else if (end - start >= CIRCLE_IN_DEGREE) { + // draw circle + start = 0; + end = CIRCLE_IN_DEGREE; + } else { + start = tempAngle; + end = GetDrawAngle(end); + } +} + +uint16_t DrawArc::CalculateTanDegree(uint16_t x, uint16_t y) +{ + uint16_t degree = FastAtan2(x, y); + if ((degree == QUARTER_IN_DEGREE) && (y != 0)) { + degree--; + } + if ((degree == 0) && (x != 0)) { + degree++; + } + return degree; +} + +void DrawArc::DrawCircleNoEndpoint(ArcInfo& arcInfo, const Rect& mask, const Style& style, uint8_t opa, bool anti) +{ + DrawAxisLine(arcInfo, mask, style, opa); + + int16_t yStart = mask.GetTop() - arcInfo.center.y; + int16_t yEnd = mask.GetBottom() - arcInfo.center.y; + if ((yStart >= 0) && (yEnd >= 0)) { + int16_t tmp = yStart; + yStart = -yEnd; + yEnd = -tmp; + } else if ((yStart < 0) && (yEnd > 0)) { + yStart = MATH_MIN(yStart, -yEnd); + yEnd = -1; + } + yStart = MATH_MAX(yStart, -outRadius_) - 1; + yEnd = MATH_MIN(yEnd, -1); + + int16_t xi; + int16_t xLineStart = -outRadius_; + int16_t xLineStart2 = xLineStart - 1; + int16_t xLineStart3 = COORD_MIN; + + for (y_ = yEnd; y_ > yStart; y_--) { + ySqr_ = static_cast(y_) * y_; + bool isSetStartPot = false; + for (xi = xLineStart2; xi < 0; xi++) { + uint32_t currentSqr = static_cast(xi) * xi + ySqr_; + if (currentSqr > outRadiusSqr_) { + continue; + } + if (!isSetStartPot) { + xLineStart2 = xi; + lineStart_ = xi; + if (xLineStart3 != COORD_MIN) { + xi = xLineStart3; + } + isSetStartPot = true; + } + if (y_ <= -inRadius_) { + lineEnd_ = -1; + xi = -1; + break; + } + if (currentSqr < inRadiusSqr_) { + xLineStart3 = xi - 1; + lineEnd_ = xi - 1; + break; + } + } + if (!isSetStartPot) { + continue; + } +#if ENABLE_ANTIALIAS + if (anti) { + DrawLineAnti(arcInfo, mask, style, opa); + } +#endif + DrawLineWithDegree(arcInfo, -lineEnd_, -lineStart_, y_, mask, style, opa, ARC_QUADRANT_ONE); + + DrawLineWithDegree(arcInfo, -lineEnd_, -lineStart_, -y_, mask, style, opa, ARC_QUADRANT_TWO); + + DrawLineWithDegree(arcInfo, lineStart_, lineEnd_, -y_, mask, style, opa, ARC_QUADRANT_THREE); + + DrawLineWithDegree(arcInfo, lineStart_, lineEnd_, y_, mask, style, opa, ARC_QUADRANT_FOUR); + } +} + +void DrawArc::DrawAxisLine(ArcInfo& arcInfo, const Rect& mask, const Style& style, uint8_t opa) +{ + int16_t lineWidth = 0; + int16_t outRadius = outRadius_ - 1; + int16_t inRadius = inRadius_; + if (inRadius <= 0) { + inRadius = 1; + DrawHorLine(arcInfo.center, arcInfo.imgPos, mask, 0, style, opa, arcInfo.imgSrc); + } + lineWidth = outRadius - inRadius; + + if (isCircle_ || (IS_IN_DEGREERANE(THREE_QUARTER_IN_DEGREE, arcInfo.startAngle, arcInfo.endAngle))) { + DrawHorLine(Point{static_cast(arcInfo.center.x - outRadius), arcInfo.center.y}, arcInfo.imgPos, mask, + lineWidth, style, opa, arcInfo.imgSrc); + } + + if (isCircle_ || (IS_IN_DEGREERANE(QUARTER_IN_DEGREE, arcInfo.startAngle, arcInfo.endAngle))) { + DrawHorLine(Point{static_cast(arcInfo.center.x + inRadius), arcInfo.center.y}, arcInfo.imgPos, mask, + lineWidth, style, opa, arcInfo.imgSrc); + } + + if (isCircle_ || (IS_IN_DEGREERANE(0, arcInfo.startAngle, arcInfo.endAngle))) { + DrawVerLine(Point{arcInfo.center.x, static_cast(arcInfo.center.y - outRadius)}, arcInfo.imgPos, mask, + lineWidth, style, opa, arcInfo.imgSrc); + } + + if (isCircle_ || (IS_IN_DEGREERANE(SEMICIRCLE_IN_DEGREE, arcInfo.startAngle, arcInfo.endAngle))) { + DrawVerLine(Point{arcInfo.center.x, static_cast(arcInfo.center.y + inRadius)}, arcInfo.imgPos, mask, + lineWidth, style, opa, arcInfo.imgSrc); + } +} + +void DrawArc::DrawLineWithDegree(ArcInfo& arcInfo, + int16_t start, + int16_t end, + int16_t y, + const Rect& mask, + const Style& style, + uint8_t opaScale, + uint8_t quadrant) +{ + if (isCircle_) { + DrawHorLine(Point{static_cast(arcInfo.center.x + start), static_cast(arcInfo.center.y + y)}, + arcInfo.imgPos, mask, end - start, style, opaScale, arcInfo.imgSrc); + return; + } + uint16_t degreeStart = GetDegreeInQuadrant(CalculateTanDegree(MATH_ABS(start), MATH_ABS(y)), quadrant); + uint16_t degreeEnd = GetDegreeInQuadrant(CalculateTanDegree(MATH_ABS(end), MATH_ABS(y)), quadrant); + if (degreeStart > degreeEnd) { + uint16_t tmp = degreeStart; + degreeStart = degreeEnd; + degreeEnd = tmp; + } + + int16_t lineDegreeRet = GetDegreeRangeIntersectState(degreeStart, degreeEnd, arcInfo.startAngle, arcInfo.endAngle); + int16_t drawEnd = 0; + switch (lineDegreeRet) { + case OUT_DEGREE_RANG: + return; + case IN_DEGREE_RANG: + DrawHorLine( + Point{static_cast(arcInfo.center.x + start), static_cast(arcInfo.center.y + y)}, + arcInfo.imgPos, mask, end - start, style, opaScale, arcInfo.imgSrc); + return; + case INTERSECT: + DrawLineWithDegreeInner(arcInfo, start, end, y, mask, style, opaScale, quadrant); + return; + case DOUBLE_INTERSECT: + drawEnd = DrawLineWithDegreeInner(arcInfo, start, end, y, mask, style, opaScale, quadrant); + DrawLineWithDegreeInner(arcInfo, drawEnd + 1, end, y, mask, style, opaScale, quadrant); + return; + default: + return; + } +} + +int16_t DrawArc::DrawLineWithDegreeInner(ArcInfo& arcInfo, + int16_t start, + int16_t end, + int16_t y, + const Rect& mask, + const Style& style, + uint8_t opaScale, + uint8_t quadrant) +{ + int16_t drawStart = COORD_MIN; + int16_t drawEnd = COORD_MIN; + for (int16_t xi = start; xi <= end; xi++) { + uint16_t degreeBase = CalculateTanDegree(MATH_ABS(xi), MATH_ABS(y)); + uint16_t degree = GetDegreeInQuadrant(degreeBase, quadrant); + if (IS_IN_DEGREERANE(degree, arcInfo.startAngle, arcInfo.endAngle)) { + if (drawStart == COORD_MIN) { + drawStart = xi; + } + } else { + if ((drawStart != COORD_MIN) && (drawEnd == COORD_MIN)) { + drawEnd = xi - 1; + break; + } + } + } + if (drawEnd == COORD_MIN) { + drawEnd = end; + } + if ((drawStart != COORD_MIN) && (drawEnd != COORD_MIN)) { + DrawHorLine( + Point{static_cast(arcInfo.center.x + drawStart), static_cast(arcInfo.center.y + y)}, + arcInfo.imgPos, mask, drawEnd - drawStart, style, opaScale, arcInfo.imgSrc); + } + return drawEnd; +} + +#if ENABLE_ANTIALIAS +void DrawArc::DrawLineAnti(ArcInfo& arcInfo, const Rect& mask, const Style& style, uint8_t opa) +{ + outAntiStart_ = lineStart_; + outAntiEnd_ = lineStart_; + inAntiStart_ = lineEnd_ + 1; + inAntiEnd_ = COORD_MIN; + + for (int16_t xAnti = lineStart_; xAnti <= lineEnd_; xAnti++) { + uint32_t currentSqr = static_cast(xAnti) * xAnti + ySqr_; + if ((currentSqr <= antiOutRadiusSqr_) || (xAnti == lineEnd_)) { + lineStart_ = xAnti; + outAntiEnd_ = xAnti - 1; + break; + } + } + + for (int16_t xAnti = lineEnd_ + 1; xAnti <= -1; xAnti++) { + uint32_t currentSqr = static_cast(xAnti) * xAnti + ySqr_; + if ((currentSqr <= antiInRadiusSqr_) || (xAnti == -1)) { + inAntiEnd_ = xAnti; + break; + } + } + + for (int16_t xAnti = outAntiStart_; xAnti <= outAntiEnd_; xAnti++) { + uint32_t currentSqr = static_cast(xAnti) * xAnti + ySqr_; + uint8_t antiOpa = + (((static_cast(outRadius_) << 1) - 1 - (currentSqr - antiOutRadiusSqr_)) * OPA_OPAQUE) / + ((outRadius_ << 1) - 1); + antiOpa = (opa == OPA_OPAQUE) ? antiOpa : (static_cast(antiOpa) * opa) >> SHIFT_8; + DrawPointAnti(arcInfo, xAnti, mask, style, antiOpa); + } + + for (int16_t xAnti = inAntiStart_; xAnti <= inAntiEnd_; xAnti++) { + uint32_t currentSqr = static_cast(xAnti) * xAnti + ySqr_; + if (currentSqr <= antiInRadiusSqr_) { + break; + } + uint8_t antiOpa = (static_cast(currentSqr - antiInRadiusSqr_) * OPA_OPAQUE) / ((inRadius_ << 1) - 1); + antiOpa = (opa == OPA_OPAQUE) ? antiOpa : (static_cast(antiOpa) * opa) >> SHIFT_8; + DrawPointAnti(arcInfo, xAnti, mask, style, antiOpa); + } +} + +void DrawArc::DrawPointAnti(ArcInfo& arcInfo, int16_t x, const Rect& mask, const Style& style, uint8_t antiOpa) +{ + int16_t startX; + int16_t starty; + uint16_t degreeBase = CalculateTanDegree(MATH_ABS(x), MATH_ABS(y_)); + if (isCircle_ || (IS_IN_DEGREERANE(CIRCLE_IN_DEGREE - degreeBase, arcInfo.startAngle, arcInfo.endAngle))) { + startX = arcInfo.center.x + x; + starty = arcInfo.center.y + y_; + DrawHorLine(Point{startX, starty}, arcInfo.imgPos, mask, 0, style, antiOpa, arcInfo.imgSrc); + } + if (isCircle_ || (IS_IN_DEGREERANE(SEMICIRCLE_IN_DEGREE + degreeBase, arcInfo.startAngle, arcInfo.endAngle))) { + startX = arcInfo.center.x + x; + starty = arcInfo.center.y - y_; + DrawHorLine(Point{startX, starty}, arcInfo.imgPos, mask, 0, style, antiOpa, arcInfo.imgSrc); + } + if (isCircle_ || (IS_IN_DEGREERANE(degreeBase, arcInfo.startAngle, arcInfo.endAngle))) { + startX = arcInfo.center.x - x; + starty = arcInfo.center.y + y_; + DrawHorLine(Point{startX, starty}, arcInfo.imgPos, mask, 0, style, antiOpa, arcInfo.imgSrc); + } + if (isCircle_ || (IS_IN_DEGREERANE(SEMICIRCLE_IN_DEGREE - degreeBase, arcInfo.startAngle, arcInfo.endAngle))) { + startX = arcInfo.center.x - x; + starty = arcInfo.center.y - y_; + DrawHorLine(Point{startX, starty}, arcInfo.imgPos, mask, 0, style, antiOpa, arcInfo.imgSrc); + } +} +#endif + +uint16_t DrawArc::GetDegreeInQuadrant(uint16_t degree, uint8_t quadrant) +{ + switch (quadrant) { + case ARC_QUADRANT_ONE: + return degree; + case ARC_QUADRANT_TWO: + return SEMICIRCLE_IN_DEGREE - degree; + case ARC_QUADRANT_THREE: + return SEMICIRCLE_IN_DEGREE + degree; + case ARC_QUADRANT_FOUR: + return CIRCLE_IN_DEGREE - degree; + default: + return degree; + } +} + +void DrawArc::Draw(ArcInfo& arcInfo, const Rect& mask, const Style& style, uint8_t opaScale, uint8_t cap) +{ + OpacityType opa = DrawUtils::GetMixOpacity(opaScale, style.lineOpa_); + if ((opa == OPA_TRANSPARENT) || (style.lineWidth_ < 1) || (arcInfo.startAngle == arcInfo.endAngle)) { + return; + } + + SetArcInfo(arcInfo, style); + + if ((arcInfo.imgSrc != nullptr) && (arcInfo.imgSrc->GetSrcType() != IMG_SRC_UNKNOWN)) { + DrawCircleNoEndpoint(arcInfo, mask, style, opa, false); + } else { + DrawCircleNoEndpoint(arcInfo, mask, style, opa, true); + } + + if (!isCircle_ && (cap == CapType::CAP_ROUND)) { + int16_t lineWidth = style.lineWidth_; + if (lineWidth > arcInfo.radius) { + lineWidth = arcInfo.radius; + } + + ArcInfo endArcInfo = arcInfo; + endArcInfo.startAngle = 0; + endArcInfo.endAngle = CIRCLE_IN_DEGREE; + + int16_t outRadius = arcInfo.radius - 1; + lineWidth--; + /* the arc radius of the round cap should be half the line width */ + endArcInfo.radius = (static_cast(lineWidth + 1) >> 1) + 1; + + /* 0.5: round up */ + float temp = (outRadius - endArcInfo.radius + 1) * Sin(arcInfo.startAngle); + int16_t startCapX = static_cast((temp > 0) ? (temp + 0.5f) : (temp - 0.5f)); + + temp = (outRadius - endArcInfo.radius + 1) * Sin(QUARTER_IN_DEGREE - arcInfo.startAngle); + int16_t startCapY = static_cast((temp > 0) ? (temp + 0.5f) : (temp - 0.5f)); + + endArcInfo.center.x += startCapX; + endArcInfo.center.y -= startCapY; + SetArcInfo(endArcInfo, style); + DrawCircleNoEndpoint(endArcInfo, mask, style, opa, true); + + temp = (outRadius - endArcInfo.radius + 1) * Sin(arcInfo.endAngle); + int16_t endCapX = static_cast((temp > 0) ? (temp + 0.5f) : (temp - 0.5f)); + + temp = (outRadius - endArcInfo.radius + 1) * Sin(QUARTER_IN_DEGREE - arcInfo.endAngle); + int16_t endCapY = static_cast((temp > 0) ? (temp + 0.5f) : (temp - 0.5f)); + + endArcInfo.center = arcInfo.center; + endArcInfo.center.x += endCapX; + endArcInfo.center.y -= endCapY; + SetArcInfo(endArcInfo, style); + DrawCircleNoEndpoint(endArcInfo, mask, style, opa, true); + } +} + +int16_t DrawArc::GetDegreeRangeIntersectState(uint16_t degreeStart, uint16_t degreeEnd, uint16_t start, uint16_t end) +{ + if (start <= end) { + if ((degreeStart >= start) && (degreeStart <= end) && (degreeEnd >= start) && (degreeEnd <= end)) { + return IN_DEGREE_RANG; + } else if ((degreeEnd < start) || (degreeStart > end)) { + return OUT_DEGREE_RANG; + } else { + return INTERSECT; + } + } else { + if (((degreeStart >= start) && (degreeEnd >= start)) || ((degreeStart <= end) && (degreeEnd <= end))) { + return IN_DEGREE_RANG; + } else if ((degreeStart > end) && (degreeEnd < start)) { + return OUT_DEGREE_RANG; + } else if ((degreeStart <= end) && (degreeEnd >= start)) { + return DOUBLE_INTERSECT; + } else { + return INTERSECT; + } + } +} +void DrawArc::SetArcInfo(ArcInfo& arcInfo, const Style& style) +{ + outRadius_ = arcInfo.radius; + inRadius_ = outRadius_ - style.lineWidth_; + if (inRadius_ < 0) { + inRadius_ = 0; + } + outRadiusSqr_ = outRadius_ * outRadius_; + inRadiusSqr_ = inRadius_ * inRadius_; + + if ((arcInfo.startAngle == 0) && (arcInfo.endAngle == CIRCLE_IN_DEGREE)) { + isCircle_ = true; + } else { + isCircle_ = false; + } +#if ENABLE_ANTIALIAS + antiOutRadiusSqr_ = (outRadius_ - 1) * (outRadius_ - 1); + if (inRadius_ == 0) { + antiInRadiusSqr_ = 0; + } else { + antiInRadiusSqr_ = (inRadius_ - 1) * (inRadius_ - 1); + } +#endif +} +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/draw/draw_arc.h b/frameworks/draw/draw_arc.h new file mode 100755 index 0000000..8b77635 --- /dev/null +++ b/frameworks/draw/draw_arc.h @@ -0,0 +1,146 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef GRAPHIC_LITE_DRAW_ARC_H +#define GRAPHIC_LITE_DRAW_ARC_H +#include "common/image.h" +#include "draw_image.h" +#include "draw_utils.h" +#include "graphic_math.h" +#include "heap_base.h" +#include "imgdecode/cache_manager.h" +#include "style.h" + +namespace OHOS { +struct ArcInfo { + Point center; + Point imgPos; + uint16_t radius; + int16_t startAngle; + int16_t endAngle; + const Image* imgSrc; +}; + +class DrawArc : public HeapBase { +public: + static DrawArc* GetInstance() + { + static DrawArc drawArc; + return &drawArc; + } + + void GetDrawRange(int16_t& start, int16_t& end); + + void Draw(ArcInfo& arcInfo, const Rect& mask, const Style& style, uint8_t opaScale, uint8_t cap); + +private: + static constexpr uint8_t DRAW_ARC_QUADRANT_NUM = 4; + static constexpr uint8_t ARC_QUADRANT_ONE = 0; + static constexpr uint8_t ARC_QUADRANT_TWO = 1; + static constexpr uint8_t ARC_QUADRANT_THREE = 2; + static constexpr uint8_t ARC_QUADRANT_FOUR = 3; + static constexpr int16_t IN_DEGREE_RANG = 0; + static constexpr int16_t OUT_DEGREE_RANG = 1; + static constexpr int16_t INTERSECT = 2; + static constexpr int16_t DOUBLE_INTERSECT = 3; + + int16_t lineStart_; + int16_t lineEnd_; + int16_t outAntiStart_; + int16_t outAntiEnd_; + int16_t inAntiStart_; + int16_t inAntiEnd_; + int16_t y_; + int16_t outRadius_; + int16_t inRadius_; + uint32_t ySqr_; + uint32_t outRadiusSqr_; + uint32_t inRadiusSqr_; + bool isCircle_; + uint32_t antiOutRadiusSqr_; + uint32_t antiInRadiusSqr_; + + DrawArc() + : lineStart_(0), + lineEnd_(0), + outAntiStart_(0), + outAntiEnd_(0), + inAntiStart_(0), + inAntiEnd_(0), + y_(0), + outRadius_(0), + inRadius_(0), + ySqr_(0), + outRadiusSqr_(0), + inRadiusSqr_(0), + isCircle_(false), + antiOutRadiusSqr_(0), + antiInRadiusSqr_(0) + { + } + ~DrawArc() {} + void DrawVerLine(const Point& begin, + const Point& imgPos, + const Rect& mask, + int16_t len, + const Style& style, + uint8_t opaScale, + const Image* imgSrc); + + void DrawHorLine(const Point& begin, + const Point& imgPos, + const Rect& mask, + int16_t len, + const Style& style, + uint8_t opaScale, + const Image* imgSrc); + + void DrawImg(const Point& imgPos, + Rect& area, + const Rect& invalidatedArea, + const Style& style, + uint8_t opaScale, + const Image* imgSrc); + + int16_t GetDegreeRangeIntersectState(uint16_t degreeStart, uint16_t degreeEnd, uint16_t start, uint16_t end); + uint16_t CalculateTanDegree(uint16_t x, uint16_t y); + int16_t GetDrawAngle(int16_t angle); + void DrawCircleNoEndpoint(ArcInfo& arcInfo, const Rect& mask, const Style& style, uint8_t opa, bool anti); + void DrawAxisLine(ArcInfo& arcInfo, const Rect& mask, const Style& style, uint8_t opa); + void DrawLineWithDegree(ArcInfo& arcInfo, + int16_t start, + int16_t end, + int16_t y, + const Rect& mask, + const Style& style, + uint8_t opaScale, + uint8_t quadrant); + int16_t DrawLineWithDegreeInner(ArcInfo& arcInfo, + int16_t start, + int16_t end, + int16_t y, + const Rect& mask, + const Style& style, + uint8_t opaScale, + uint8_t quadrant); +#if ENABLE_ANTIALIAS + void DrawLineAnti(ArcInfo& arcInfo, const Rect& mask, const Style& style, uint8_t opa); + void DrawPointAnti(ArcInfo& arcInfo, int16_t x, const Rect& mask, const Style& style, uint8_t antiOpa); +#endif + uint16_t GetDegreeInQuadrant(uint16_t degree, uint8_t quadrant); + void SetArcInfo(ArcInfo& arcInfo, const Style& style); +}; +} // namespace OHOS +#endif // GRAPHIC_LITE_DRAW_ARC_H diff --git a/frameworks/draw/draw_curve.cpp b/frameworks/draw/draw_curve.cpp new file mode 100755 index 0000000..ef18ffa --- /dev/null +++ b/frameworks/draw/draw_curve.cpp @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "draw/draw_curve.h" +#include "animator/interpolation.h" +#include "draw/draw_line.h" + +namespace OHOS { +void DrawCurve::DrawCubicBezier(const Point& start, const Point& control1, const Point& control2, const Point& end, + const Rect& mask, int16_t width, const ColorType& color, OpacityType opacity) +{ + if ((width == 0) || (opacity == OPA_TRANSPARENT)) { + return; + } + + Point prePoint = start; + for (int16_t t = 1; t <= INTERPOLATION_RANGE; t++) { + Point point; + point.x = Interpolation::GetBezierInterpolation(t, start.x, control1.x, control2.x, end.x); + point.y = Interpolation::GetBezierInterpolation(t, start.y, control1.y, control2.y, end.y); + if ((prePoint.x == point.x) && (prePoint.y == point.y)) { + continue; + } + DrawLine::Draw(prePoint, point, mask, width, color, opacity); + prePoint = point; + } +} +} diff --git a/frameworks/draw/draw_curve.h b/frameworks/draw/draw_curve.h new file mode 100755 index 0000000..3ac0958 --- /dev/null +++ b/frameworks/draw/draw_curve.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef GRAPHIC_LITE_DRAW_CURVE_H +#define GRAPHIC_LITE_DRAW_CURVE_H + +#include "color.h" +#include "geometry2d.h" + +namespace OHOS { +class DrawCurve : public HeapBase { +public: + static void DrawCubicBezier(const Point& start, const Point& control1, const Point& control2, const Point& end, + const Rect& mask, int16_t width, const ColorType& color, OpacityType opacity); +private: + static constexpr uint16_t INTERPOLATION_RANGE = 1024; +}; +} // namespace OHOS +#endif // GRAPHIC_LITE_DRAW_CURVE_H \ No newline at end of file diff --git a/frameworks/draw/draw_image.cpp b/frameworks/draw/draw_image.cpp new file mode 100755 index 0000000..40ce6de --- /dev/null +++ b/frameworks/draw/draw_image.cpp @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "draw/draw_image.h" + +#include "color.h" +#include "graphic_log.h" +#include "imgdecode/cache_manager.h" + +namespace OHOS { +void DrawImage::DrawCommon(const Rect& coords, const Rect& mask, + const ImageInfo* img, const Style& style, uint8_t opaScale) +{ + if (img == nullptr) { + return; + } + OpacityType opa = DrawUtils::GetMixOpacity(opaScale, style.imageOpa_); + + /* 3 : when single pixel change bit to byte, the buffer should divide by 8, equal to shift right 3 bits. */ + uint8_t pxByteSize = DrawUtils::GetPxSizeByImageInfo(*img) >> 3; + DrawUtils::GetInstance()->DrawImage(coords, mask, img->data, opa, pxByteSize); +} + +void DrawImage::DrawCommon(const Rect& coords, const Rect& mask, + const char* path, const Style& style, uint8_t opaScale) +{ + if (path == nullptr) { + return; + } + OpacityType opa = DrawUtils::GetMixOpacity(opaScale, style.imageOpa_); + + CacheEntry entry; + if (CacheManager::GetInstance().Open(path, style, entry) != RetCode::OK) { + return; + } + + /* 3 : when single pixel change bit to byte, the buffer should divide by 8, equal to shift right 3 bits. */ + uint8_t pxByteSize = DrawUtils::GetPxSizeByImageInfo(entry.GetImageInfo()) >> 3; + if (entry.InCache()) { + DrawUtils::GetInstance()->DrawImage(coords, mask, entry.GetImgData(), opa, pxByteSize); + } else { + Rect valid = coords; + if (!valid.Intersect(valid, mask)) { + return; + } + + int16_t width = valid.GetWidth(); + if (width <= 0) { + return; + } + uint8_t* buf = static_cast(UIMalloc(static_cast(width) * ((COLOR_DEPTH >> SHIFT_3) + 1))); + if (buf == nullptr) { + return; + } + + Rect line = valid; + line.SetHeight(1); + Point start; + start.x = valid.GetLeft() - coords.GetLeft(); + start.y = valid.GetTop() - coords.GetTop(); + int16_t row; + for (row = valid.GetTop(); row <= valid.GetBottom(); row++) { + if (entry.ReadLine(start, width, buf) != RetCode::OK) { + CacheManager::GetInstance().Close(path); + UIFree(buf); + return; + } + DrawUtils::GetInstance()->DrawImage(line, mask, buf, opa, pxByteSize); + line.SetTop(line.GetTop() + 1); + line.SetBottom(line.GetBottom() + 1); + start.y++; + } + UIFree(buf); + } +} +} // namespace OHOS diff --git a/frameworks/draw/draw_image.h b/frameworks/draw/draw_image.h new file mode 100755 index 0000000..537548d --- /dev/null +++ b/frameworks/draw/draw_image.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef GRAPHIC_LITE_DRAW_IMAGE_H +#define GRAPHIC_LITE_DRAW_IMAGE_H + +#include +#include +#include "components/ui_view.h" +#include "draw_utils.h" +#include "geometry2d.h" + +namespace OHOS { +class CacheEntry; + +class DrawImage : public HeapBase { +public: + DrawImage() {} + ~DrawImage() {} + + static void DrawCommon(const Rect& coords, const Rect& mask, + const ImageInfo* img, const Style& style, uint8_t opaScale); + + static void DrawCommon(const Rect& coords, const Rect& mask, + const char* path, const Style& style, uint8_t opaScale); +}; +} // namespace OHOS + +#endif // GRAPHIC_LITE_DRAW_IMAGE_H diff --git a/frameworks/draw/draw_label.cpp b/frameworks/draw/draw_label.cpp new file mode 100755 index 0000000..8311e88 --- /dev/null +++ b/frameworks/draw/draw_label.cpp @@ -0,0 +1,167 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "draw/draw_label.h" +#include +#include "common/typed_text.h" +#include "draw/draw_utils.h" +#include "font/ui_font.h" +#include "font/ui_font_header.h" +#include "graphic_log.h" + +namespace OHOS { +void DrawLabel::DrawTextOneLine(const LabelLineInfo& labelLine) +{ + UIFont* fontEngine = UIFont::GetInstance(); + if (labelLine.direct == TEXT_DIRECT_RTL) { + labelLine.pos.x -= labelLine.offset.x; + } else { + labelLine.pos.x += labelLine.offset.x; + } + + uint32_t i = 0; + uint32_t letter; + uint16_t letterWidth; + while (i < labelLine.lineLength) { + letter = TypedText::GetUTF8Next(labelLine.text, i, i); + + LabelLetterInfo letterInfo{labelLine.pos, + labelLine.mask, + labelLine.style.textColor_, + labelLine.opaScale, + 0, + 0, + letter, + labelLine.direct, + labelLine.fontId, + 0, + labelLine.fontSize}; + DrawUtils::GetInstance()->DrawLetter(letterInfo); + letterWidth = fontEngine->GetWidth(letter, 0); + if (labelLine.direct == TEXT_DIRECT_RTL) { + labelLine.pos.x -= (letterWidth + labelLine.style.letterSpace_); + } else { + labelLine.pos.x += (letterWidth + labelLine.style.letterSpace_); + } + } +} + +void DrawLabel::DrawArcText(const Rect& mask, + const char* text, + const Point& arcCenter, + uint8_t fontId, + const UIArcLabel::ArcTextInfo arcTextInfo, + UIArcLabel::TextOrientation orientation, + const Style& style, + OpacityType opaScale) +{ + if ((text == nullptr) || (arcTextInfo.lineStart == arcTextInfo.lineEnd) || (arcTextInfo.radius == 0)) { + GRAPHIC_LOGE("DrawLabel::DrawArcText invalid parameter\n"); + return; + } + OpacityType opa = DrawUtils::GetMixOpacity(opaScale, style.textOpa_); + if (opa == OPA_TRANSPARENT) { + return; + } + uint16_t letterWidth; + uint16_t letterHeight = UIFont::GetInstance()->GetHeight(); + uint32_t i = arcTextInfo.lineStart; + float angle = arcTextInfo.startAngle; + float posX; + float posY; + float rotateAngle; + bool xorFlag = (orientation == UIArcLabel::TextOrientation::INSIDE) ^ (arcTextInfo.direct == TEXT_DIRECT_LTR); + + while (i < arcTextInfo.lineEnd) { + uint32_t tmp = i; + uint32_t letter = TypedText::GetUTF8Next(text, tmp, i); + if (letter == 0) { + continue; + } + if ((letter == '\r') || (letter == '\n')) { + break; + } + letterWidth = UIFont::GetInstance()->GetWidth(letter, 0); + if ((tmp == arcTextInfo.lineStart) && xorFlag) { + angle += TypedText::GetAngleForArcLen(static_cast(letterWidth), letterHeight, arcTextInfo.radius, + arcTextInfo.direct, orientation); + } + uint16_t arcLen = letterWidth + style.letterSpace_; + if (arcLen == 0) { + continue; + } + float incrementAngle = TypedText::GetAngleForArcLen(static_cast(arcLen), letterHeight, + arcTextInfo.radius, arcTextInfo.direct, orientation); + + rotateAngle = (orientation == UIArcLabel::TextOrientation::INSIDE) ? angle : (angle - SEMICIRCLE_IN_DEGREE); + + // 2: half + float fineTuningAngle = incrementAngle * (static_cast(letterWidth) / (2 * arcLen)); + rotateAngle += (xorFlag ? -fineTuningAngle : fineTuningAngle); + TypedText::GetArcLetterPos(arcCenter, arcTextInfo.radius, angle, posX, posY); + angle += incrementAngle; + + DrawLetterWithRotate(mask, fontId, letter, Point{MATH_ROUND(posX), MATH_ROUND(posY)}, + static_cast(rotateAngle), style.textColor_, opaScale); + } +} + +void DrawLabel::DrawLetterWithRotate(const Rect& mask, + uint8_t fontId, + uint32_t letter, + const Point& pos, + int16_t rotateAngle, + const ColorType& color, + OpacityType opaScale) +{ + UIFont* fontEngine = UIFont::GetInstance(); + FontHeader head; + GlyphNode node; + if (fontEngine->GetCurrentFontHeader(head) != 0) { + return; + } + + const uint8_t* fontMap = fontEngine->GetBitmap(letter, node, 0); + if (fontMap == nullptr) { + return; + } + uint8_t fontWeight = fontEngine->GetFontWeight(fontId); + ColorMode colorMode; + switch (fontWeight) { + case FONT_WEIGHT_1: + colorMode = A1; + break; + case FONT_WEIGHT_2: + colorMode = A2; + break; + case FONT_WEIGHT_4: + colorMode = A4; + break; + case FONT_WEIGHT_8: + colorMode = A8; + break; + default: + return; + } + Rect rectLetter; + rectLetter.SetPosition(pos.x + node.left, pos.y + head.ascender - node.top); + rectLetter.Resize(node.cols, node.rows); + TransformMap transMap(rectLetter); + transMap.Rotate(rotateAngle, Vector2(-node.left, node.top - head.ascender)); + TransformDataInfo letterTranDataInfo = {ImageHeader{colorMode, 0, 0, 0, node.cols, node.rows}, fontMap, fontWeight, + BlurLevel::LEVEL0}; + DrawUtils::GetInstance()->DrawTransform(mask, Point{0, 0}, color, opaScale, transMap, letterTranDataInfo); +} +} // namespace OHOS diff --git a/frameworks/draw/draw_label.h b/frameworks/draw/draw_label.h new file mode 100755 index 0000000..c72741c --- /dev/null +++ b/frameworks/draw/draw_label.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef GRAPHIC_LITE_DRAW_LABEL_H +#define GRAPHIC_LITE_DRAW_LABEL_H + +#include "common/typed_text.h" +#include "draw/draw_utils.h" +#include "geometry2d.h" +#include "heap_base.h" +#include "style.h" + +namespace OHOS { +class DrawLabel : public HeapBase { +public: + static void DrawTextOneLine(const LabelLineInfo& labelLine); + + static void DrawArcText(const Rect& mask, const char* text, const Point& arcCenter, uint8_t fontId, + const UIArcLabel::ArcTextInfo arcTextInfo, UIArcLabel::TextOrientation orientation, const Style& style, + uint8_t opaScale); + + static void DrawLetterWithRotate(const Rect& mask, uint8_t fontId, uint32_t letter, const Point& pos, + int16_t rotateAngle, const ColorType& color, OpacityType opaScale); +}; +} // namespace OHOS +#endif // GRAPHIC_LITE_DRAW_LABEL_H diff --git a/frameworks/draw/draw_line.cpp b/frameworks/draw/draw_line.cpp new file mode 100755 index 0000000..ffb26a0 --- /dev/null +++ b/frameworks/draw/draw_line.cpp @@ -0,0 +1,472 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "draw/draw_line.h" +#include "draw/draw_utils.h" +#include "graphic_math.h" + +namespace OHOS { +#define INCREASE_ACC(acc, accTemp, adj, step, dir) \ + do { \ + (accTemp) = (acc); \ + (acc) += (adj); \ + if ((acc) <= (accTemp)) { \ + (step) += (dir); \ + } \ + } while (0) + +#define SWAP_START_END(sx, sy, ex, ey, dx, dy, dir) \ + do { \ + if ((dy) >= (dx)) { \ + if ((sy) > (ey)) { \ + SWAP_POINTS((sx), (ex), (sy), (ey)); \ + } \ + if ((ex) < (sx)) { \ + (dir) = -1; \ + } \ + } else { \ + if ((sx) < (ex)) { \ + SWAP_POINTS((sx), (ex), (sy), (ey)); \ + } \ + if ((ey) < (sy)) { \ + (dir) = -1; \ + } \ + } \ + } while (0) + +#define SWAP_IF_Y_LARGER(x1, x2, y1, y2) \ + if ((y1) > (y2)) { \ + SWAP_POINTS((x1), (x2), (y1), (y2)); \ + } + +#define SWAP_IF_X_SMALLER(x1, x2, y1, y2) \ + if ((x1) < (x2)) { \ + SWAP_POINTS((x1), (x2), (y1), (y2)); \ + } + +void DrawLine::Draw(const Point& start, + const Point& end, + const Rect& mask, + int16_t width, + const ColorType& color, + OpacityType opacity) +{ + if ((width == 0) || (opacity == OPA_TRANSPARENT)) { + return; + } + + int16_t yTop; + int16_t yBottom; + + if (start.y < end.y) { + yTop = start.y - width / 2; // 2: half + yBottom = end.y + width / 2; // 2: half + } else { + yTop = end.y - width / 2; // 2: half + yBottom = start.y + width / 2; // 2: half + } + + if ((yBottom < mask.GetTop()) || (yTop > mask.GetBottom())) { + return; + } + + if (start.y == end.y) { + DrawHorizontalLine(start, end, mask, width, color, opacity); + } else if (start.x == end.x) { + DrawVerticalLine(start, end, mask, width, color, opacity); + } else { + DrawWuLine(start, end, mask, width, color, opacity); + } +} + +void DrawLine::DrawVerticalLine(const Point& start, + const Point& end, + const Rect& mask, + int16_t width, + const ColorType& color, + OpacityType opacity) +{ + Rect rect; + + if (start.y < end.y) { + rect.SetX(start.x - width / 2); // 2: half + rect.SetY(start.y); + rect.SetWidth(width); + rect.SetHeight(end.y - start.y + 1); + } else { + rect.SetX(end.x - width / 2); // 2: half + rect.SetY(end.y); + rect.SetWidth(width); + rect.SetHeight(start.y - end.y + 1); + } + + DrawUtils::GetInstance()->DrawColorArea(rect, mask, color, opacity); +} + +void DrawLine::DrawHorizontalLine(const Point& start, + const Point& end, + const Rect& mask, + int16_t width, + const ColorType& color, + OpacityType opacity) +{ + Rect rect; + + if (start.x < end.x) { + rect.SetX(start.x); + rect.SetY(start.y - width / 2); // 2: half + rect.SetWidth(end.x - start.x + 1); + rect.SetHeight(width); + } else { + rect.SetX(end.x); + rect.SetY(end.y - width / 2); // 2: half + rect.SetWidth(start.x - end.x + 1); + rect.SetHeight(width); + } + + DrawUtils::GetInstance()->DrawColorArea(rect, mask, color, opacity); +} + +void DrawLine::DrawWuLine(const Point& start, const Point& end, const Rect& mask, + int16_t width, const ColorType& color, OpacityType opacity) +{ + if (width <= 2) { // 2 : thin line width + DrawThinWuLine(start, end, mask, width, color, opacity); + return; + } + + int16_t sx = start.x; + int16_t sy = start.y; + int16_t ex = end.x; + int16_t ey = end.y; + uint16_t dx = MATH_ABS(ex - sx); + uint16_t dy = MATH_ABS(ey - sy); + int8_t dir = 1; + SWAP_START_END(sx, sy, ex, ey, dx, dy, dir); + + // calculate four vertex ordered according to dy and dx + float plot = -static_cast(ex - sx) / static_cast(ey - sy); + float offset = 1 / (1 + plot * plot); + offset = Sqrt(offset) * width / 2; // 2: half + float x0 = sx + offset; + float y0 = sy + (x0 - sx) * plot; + float x1 = sx - offset; + float y1 = sy + (x1 - sx) * plot; + float x2 = ex + offset; + float y2 = ey + (x2 - ex) * plot; + float x3 = ex - offset; + float y3 = ey + (x3 - ex) * plot; + int16_t x0Int = MATH_ROUND(x0); + int16_t y0Int = MATH_ROUND(y0); + int16_t x1Int = MATH_ROUND(x1); + int16_t y1Int = MATH_ROUND(y1); + int16_t x2Int = MATH_ROUND(x2); + int16_t y2Int = MATH_ROUND(y2); + int16_t x3Int = MATH_ROUND(x3); + int16_t y3Int = MATH_ROUND(y3); + // width is longer than distance between start point and end point, need swap direction of line. + if (dx * dx + dy * dy < width * width) { + if ((dx == 1) && (dy == 1)) { + DrawThinWuLine({ x0Int, y0Int }, { x3Int, y3Int }, mask, 2, color, opacity); // 2 : width of line + return; + } + dx = MATH_ABS(x0Int - x1Int); + dy = MATH_ABS(y0Int - y1Int); + if (dy == dx) { + dir = -dir; + } + } + if (dy >= dx) { + SWAP_IF_Y_LARGER(x0Int, x1Int, y0Int, y1Int); + SWAP_IF_Y_LARGER(x1Int, x2Int, y1Int, y2Int); + SWAP_IF_Y_LARGER(x2Int, x3Int, y2Int, y3Int); + SWAP_IF_Y_LARGER(x0Int, x1Int, y0Int, y1Int); + SWAP_IF_Y_LARGER(x1Int, x2Int, y1Int, y2Int); + SWAP_IF_Y_LARGER(x0Int, x1Int, y0Int, y1Int); + if (dir == -1) { + SWAP_IF_X_SMALLER(x1Int, x0Int, y1Int, y0Int); + SWAP_IF_X_SMALLER(x3Int, x2Int, y3Int, y2Int); + } else { + SWAP_IF_X_SMALLER(x0Int, x1Int, y0Int, y1Int); + SWAP_IF_X_SMALLER(x2Int, x3Int, y2Int, y3Int); + } + } else { + SWAP_IF_X_SMALLER(x0Int, x1Int, y0Int, y1Int); + SWAP_IF_X_SMALLER(x1Int, x2Int, y1Int, y2Int); + SWAP_IF_X_SMALLER(x2Int, x3Int, y2Int, y3Int); + SWAP_IF_X_SMALLER(x0Int, x1Int, y0Int, y1Int); + SWAP_IF_X_SMALLER(x1Int, x2Int, y1Int, y2Int); + SWAP_IF_X_SMALLER(x0Int, x1Int, y0Int, y1Int); + if (dir == 1) { + SWAP_IF_Y_LARGER(x1Int, x0Int, y1Int, y0Int); + SWAP_IF_Y_LARGER(x3Int, x2Int, y3Int, y2Int); + } else { + SWAP_IF_Y_LARGER(x0Int, x1Int, y0Int, y1Int); + SWAP_IF_Y_LARGER(x2Int, x3Int, y2Int, y3Int); + } + } + + uint64_t adj0; + uint16_t accTemp0; + uint16_t acc0 = 0; + uint64_t adj1; + uint16_t accTemp1; + uint16_t acc1 = 0; + uint16_t accTemp2; + uint16_t acc2 = 0; + + int16_t endPoints0[MAX_LINE_WIDTH] = { 0 }; + int16_t endPoints1[MAX_LINE_WIDTH] = { 0 }; + int16_t temp0 = 0; + int16_t temp1 = 0; + int16_t edge0 = 0; + int16_t edge1 = 0; + Rect rect; + + // sort points + if (dy >= dx) { + adj0 = static_cast(dx << SHIFT_16) / static_cast(dy); + adj1 = static_cast(MATH_ABS(y1Int - y0Int) << SHIFT_16) / + static_cast(MATH_ABS(x1Int - x0Int)); + if (adj1 != 0) { + // draw top line + dx = MATH_ABS(x1Int - x0Int); + sx = x0Int; + sy = y0Int; + DrawUtils::GetInstance()->DrawPixel(x0Int, y0Int, mask, color, opacity); + while (--dx) { + accTemp1 = acc1; + acc1 += adj1; + if (acc1 <= accTemp1) { + if (sy - y0Int < MAX_LINE_WIDTH) { + endPoints0[sy - y0Int] = sx; + } + sy++; + } + sx -= dir; + DrawUtils::GetInstance()->DrawPixelInLine(sx, sy, mask, color, opacity, + (acc1 >> SHIFT_8) ^ OPA_OPAQUE); + } + if (sy - y0Int < MAX_LINE_WIDTH) { + endPoints0[sy - y0Int] = sx - dir; + } + + // draw botttom line + acc1 = 0; + dx = MATH_ABS(x3Int - x2Int); + sy = y3Int; + sx = x3Int; + DrawUtils::GetInstance()->DrawPixel(x3Int, y3Int, mask, color, opacity); + while (--dx) { + accTemp1 = acc1; + acc1 += adj1; + if (acc1 <= accTemp1) { + if (temp1 < MAX_LINE_WIDTH) { + endPoints1[temp1++] = sx; + } + sy--; + } + sx += dir; + DrawUtils::GetInstance()->DrawPixelInLine(sx, sy, mask, color, opacity, (acc1 >> SHIFT_8) ^ OPA_OPAQUE); + } + if (temp1 < MAX_LINE_WIDTH) { + endPoints1[temp1++] = sx + dir; + } + } else { + /* If y0 is equal to y1, draw two horizontal lines as the top line and bottom line. */ + rect.SetRect(MATH_MIN(x0Int, x1Int), y0Int, MATH_MAX(x0Int, x1Int), y1Int); + DrawUtils::GetInstance()->DrawColorArea(rect, mask, color, opacity); + rect.SetRect(MATH_MIN(x2Int, x3Int), y3Int, MATH_MAX(x2Int, x3Int), y2Int); + DrawUtils::GetInstance()->DrawColorArea(rect, mask, color, opacity); + } + + sx = x0Int; + sy = y0Int + 1; + dy = MATH_ABS(y3Int - y0Int); + if (dy == 0) { + return; + } + int16_t sxTemp = x1Int; + while (--dy) { + if (sy <= y1Int) { + INCREASE_ACC(acc0, accTemp0, adj0, sx, dir); + DrawUtils::GetInstance()->DrawPixelInLine(sx + dir, sy, mask, color, opacity, acc0 >> SHIFT_8); + if (temp0 < MAX_LINE_WIDTH) { + edge0 = endPoints0[temp0++]; + } + edge1 = sx; + } else if (sy < y2Int) { + INCREASE_ACC(acc0, accTemp0, adj0, sx, dir); + INCREASE_ACC(acc2, accTemp2, adj0, sxTemp, dir); + DrawUtils::GetInstance()->DrawPixelInLine(sx + dir, sy, mask, color, opacity, acc0 >> SHIFT_8); + DrawUtils::GetInstance()->DrawPixelInLine(sxTemp, sy, mask, color, opacity, + (acc2 >> SHIFT_8) ^ OPA_OPAQUE); + edge0 = sxTemp + dir; + edge1 = sx; + } else if (sy < y3Int) { + INCREASE_ACC(acc2, accTemp2, adj0, sxTemp, dir); + DrawUtils::GetInstance()->DrawPixelInLine(sxTemp, sy, mask, color, opacity, + (acc2 >> SHIFT_8) ^ OPA_OPAQUE); + edge0 = sxTemp + dir; + if (temp1 > 0) { + edge1 = endPoints1[--temp1]; + } + } + if ((dir < 0) && (edge0 > edge1)) { + SWAP_INT16(edge0, edge1); + } + rect.SetRect(edge0, sy, edge1, sy); + DrawUtils::GetInstance()->DrawColorArea(rect, mask, color, opacity); + sy++; + } + } else { + adj0 = static_cast(dy << SHIFT_16) / static_cast(dx); + adj1 = static_cast(MATH_ABS(x1Int - x0Int) << SHIFT_16) / + static_cast(MATH_ABS(y1Int - y0Int)); + if (adj1 != 0) { + // draw top line + dy = MATH_ABS(y1Int - y0Int); + sx = x0Int; + sy = y0Int; + DrawUtils::GetInstance()->DrawPixel(sx, sy, mask, color, opacity); + while (--dy) { + accTemp1 = acc1; + acc1 += adj1; + if (acc1 <= accTemp1) { + if (x0Int - sx < MAX_LINE_WIDTH) { + endPoints0[x0Int - sx] = sy; + } + sx--; + } + sy -= dir; + DrawUtils::GetInstance()->DrawPixelInLine(sx, sy, mask, color, opacity, + (acc1 >> SHIFT_8) ^ OPA_OPAQUE); + } + if (x0Int - sx < MAX_LINE_WIDTH) { + endPoints0[x0Int - sx] = sy - dir; + } + + // draw botttom line + acc1 = 0; + dy = MATH_ABS(y3Int - y2Int); + sy = y3Int; + sx = x3Int; + while (--dy) { + accTemp1 = acc1; + acc1 += adj1; + if (acc1 <= accTemp1) { + if (temp1 < MAX_LINE_WIDTH) { + endPoints1[temp1++] = sy; + } + sx++; + } + sy += dir; + DrawUtils::GetInstance()->DrawPixelInLine(sx, sy, mask, color, opacity, (acc1 >> SHIFT_8) ^ OPA_OPAQUE); + } + DrawUtils::GetInstance()->DrawPixel(x3Int, y3Int, mask, color, opacity); + if (temp1 < MAX_LINE_WIDTH) { + endPoints1[temp1++] = sy + dir; + } + } else { + /* If x0 is equal to x1, draw two vertical lines as the top line and bottom line. */ + rect.SetRect(x1Int, MATH_MIN(y0Int, y1Int), x0Int, MATH_MAX(y0Int, y1Int)); + DrawUtils::GetInstance()->DrawColorArea(rect, mask, color, opacity); + rect.SetRect(x3Int, MATH_MIN(y2Int, y3Int), x2Int, MATH_MAX(y2Int, y3Int)); + DrawUtils::GetInstance()->DrawColorArea(rect, mask, color, opacity); + } + + sx = x0Int - 1; + sy = y0Int; + dx = MATH_ABS(x3Int - x0Int); + int16_t syTemp = y1Int; + if (dx == 0) { + return; + } + while (--dx) { + if (sx >= x1Int) { + INCREASE_ACC(acc0, accTemp0, adj0, sy, dir); + DrawUtils::GetInstance()->DrawPixelInLine(sx, sy + dir, mask, color, opacity, acc0 >> SHIFT_8); + if (temp0 < MAX_LINE_WIDTH) { + edge0 = endPoints0[temp0++]; + } + edge1 = sy; + } else if (sx > x2Int) { + INCREASE_ACC(acc0, accTemp0, adj0, sy, dir); + INCREASE_ACC(acc2, accTemp2, adj0, syTemp, dir); + DrawUtils::GetInstance()->DrawPixelInLine(sx, sy + dir, mask, color, opacity, acc0 >> SHIFT_8); + DrawUtils::GetInstance()->DrawPixelInLine(sx, syTemp, mask, color, opacity, + (acc2 >> SHIFT_8) ^ OPA_OPAQUE); + edge0 = syTemp + dir; + edge1 = sy; + } else if (sx > x3Int) { + INCREASE_ACC(acc2, accTemp2, adj0, syTemp, dir); + DrawUtils::GetInstance()->DrawPixelInLine(sx, syTemp, mask, color, opacity, + (acc2 >> SHIFT_8) ^ OPA_OPAQUE); + edge0 = syTemp + dir; + if (temp1 > 0) { + edge1 = endPoints1[--temp1]; + } + } + if ((dir < 0) && (edge0 > edge1)) { + SWAP_INT16(edge0, edge1); + } + rect.SetRect(sx, edge0, sx, edge1); + DrawUtils::GetInstance()->DrawColorArea(rect, mask, color, opacity); + sx--; + } + } +} + +void DrawLine::DrawThinWuLine(const Point& start, const Point& end, const Rect& mask, + int16_t width, const ColorType& color, OpacityType opacity) +{ + int16_t sx = start.x; + int16_t sy = start.y; + int16_t ex = end.x; + int16_t ey = end.y; + uint16_t dx = MATH_ABS(ex - sx); + uint16_t dy = MATH_ABS(ey - sy); + uint64_t adj; + uint16_t accTemp; + uint16_t acc = 0; + int8_t dir = 1; + SWAP_START_END(sx, sy, ex, ey, dx, dy, dir); + if (dy >= dx) { + adj = static_cast(dx << SHIFT_16) / static_cast(dy); + while (dy--) { + INCREASE_ACC(acc, accTemp, adj, sx, dir); + sy++; + if (width == 1) { + DrawUtils::GetInstance()->DrawAdjPixelInLine(sx, sy, sx + dir, sy, mask, color, opacity, + acc >> SHIFT_8); + } else { + DrawUtils::GetInstance()->DrawVerPixelInLine(sx, sy, dir, mask, color, opacity, acc >> SHIFT_8); + } + } + } else { + adj = static_cast(dy << SHIFT_16) / static_cast(dx); + while (dx--) { + INCREASE_ACC(acc, accTemp, adj, sy, dir); + sx--; + if (width == 1) { + DrawUtils::GetInstance()->DrawAdjPixelInLine(sx, sy, sx, sy + dir, mask, color, opacity, + acc >> SHIFT_8); + } else { + DrawUtils::GetInstance()->DrawHorPixelInLine(sx, sy, dir, mask, color, opacity, acc >> SHIFT_8); + } + } + } +} +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/draw/draw_line.h b/frameworks/draw/draw_line.h new file mode 100755 index 0000000..a53d361 --- /dev/null +++ b/frameworks/draw/draw_line.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef GRAPHIC_LITE_DRAW_LINE_H +#define GRAPHIC_LITE_DRAW_LINE_H + +#include "color.h" +#include "geometry2d.h" + +namespace OHOS { +class DrawLine : public HeapBase { +public: + static void Draw(const Point& start, const Point& end, const Rect& mask, + int16_t width, const ColorType& color, OpacityType opacity); + +private: + static void DrawVerticalLine(const Point& start, const Point& end, const Rect& mask, + int16_t width, const ColorType& color, OpacityType opacity); + static void DrawHorizontalLine(const Point& start, const Point& end, const Rect& mask, + int16_t width, const ColorType& color, OpacityType opacity); + static void DrawWuLine(const Point& start, const Point& end, const Rect& mask, + int16_t width, const ColorType& color, OpacityType opacity); + static void DrawThinWuLine(const Point& start, const Point& end, const Rect& mask, + int16_t width, const ColorType& color, OpacityType opacity); +}; +} // namespace OHOS +#endif // GRAPHIC_LITE_DRAW_LINE_H diff --git a/frameworks/draw/draw_rect.cpp b/frameworks/draw/draw_rect.cpp new file mode 100755 index 0000000..4594e34 --- /dev/null +++ b/frameworks/draw/draw_rect.cpp @@ -0,0 +1,728 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "draw/draw_rect.h" +#include "draw/draw_arc.h" +#include "draw/draw_utils.h" +#include "graphic_log.h" +#include "graphic_math.h" +#include "style.h" + +namespace OHOS { +void DrawRect::Draw(const Rect& rect, const Rect& dirtyRect, const Style& style, OpacityType opaScale) +{ + if ((rect.GetWidth() <= 0) || (rect.GetHeight() <= 0)) { + GRAPHIC_LOGD("DrawRect::Draw width or height is zero\n"); + return; + } + + /** + * no border + * radius = 0 (1/4) + * radius > 0 (2/4) + * rect width > rect height + * radius >= rect height / 2 + * radius < rect height / 2 + * rect width <= rect height + * radius >= rect width / 2 + * radius < rect width / 2 + * have border + * radius = 0 (3/4) + * radius > 0 (4/4) + * radius < border width (4.1/4) + * radius = border width (4.2/4) + * radius > border width (4.3/4) + * rect width <= rect height + * radius >= border width + rect height / 2 + * radius < border width + rect height / 2 + * rect width > rect height + * radius >= border width + rect height / 2 + * radius < border width + rect height / 2 + */ + if (style.borderWidth_ == 0) { + if (style.borderRadius_ == 0) { + /* no border no radius (1/4) */ + OpacityType opa = DrawUtils::GetMixOpacity(opaScale, style.bgOpa_); + DrawUtils::GetInstance()->DrawColorArea(rect, dirtyRect, style.bgColor_, opa); + return; + } else { + /* [2/4] no border with radius (2/4) */ + DrawRectRadiusWithoutBorder(rect, dirtyRect, style, opaScale); + } + } else { + if (style.borderRadius_ == 0) { + /* [3/4] border without radius (3/4) */ + DrawRectBorderWithoutRadius(rect, dirtyRect, style, opaScale); + } else if (style.borderRadius_ < style.borderWidth_) { + /* [4.1/4] radius < border width */ + DrawRectRadiusSmallThanBorder(rect, dirtyRect, style, opaScale); + } else if (style.borderRadius_ == style.borderWidth_) { + /* [4.2/4] radius = border width */ + DrawRectRadiusEqualBorder(rect, dirtyRect, style, opaScale); + } else { + /* [4.3/4] radius >= border width + rect height_or_width / 2 */ + DrawRectRadiusBiggerThanBorder(rect, dirtyRect, style, opaScale); + } + } +} + +void DrawRect::DrawRectRadiusWithoutBorder(const Rect& rect, const Rect& dirtyRect, const Style& style, + OpacityType opaScale) +{ + // 2 : half + if ((rect.GetWidth() > rect.GetHeight()) && (style.borderRadius_ >= rect.GetHeight() / 2)) { + DrawRectRadiusWithoutBorderCon1(rect, dirtyRect, style, opaScale); + } else if ((rect.GetWidth() < rect.GetHeight()) && (style.borderRadius_ >= rect.GetWidth() / 2)) { + DrawRectRadiusWithoutBorderCon2(rect, dirtyRect, style, opaScale); + } else if ((rect.GetWidth() == rect.GetHeight()) && (style.borderRadius_ >= rect.GetWidth() / 2)) { + DrawRectRadiusWithoutBorderCon3(rect, dirtyRect, style, opaScale); + } else { + DrawRectRadiusWithoutBorderCon4(rect, dirtyRect, style, opaScale); + } +} + +void DrawRect::DrawRectRadiusWithoutBorderCon1(const Rect& rect, const Rect& dirtyRect, const Style& style, + OpacityType opaScale) +{ + int16_t radius = rect.GetHeight() / 2; + int16_t col2X = rect.GetLeft() + radius - 1; + int16_t col3X = rect.GetRight() - radius + 1; + + int16_t row1Y = rect.GetTop(); + int16_t row2Y = rect.GetTop() + radius - 1; + int16_t row3Y = rect.GetBottom(); + + Style arcStyle = style; + arcStyle.lineWidth_ = radius; + arcStyle.lineColor_ = style.bgColor_; + arcStyle.lineOpa_ = style.bgOpa_; + // draw left sector + ArcInfo arcInfo; + arcInfo.center = {col2X, row2Y}; + arcInfo.radius = radius; + arcInfo.startAngle = SEMICIRCLE_IN_DEGREE; + arcInfo.endAngle = CIRCLE_IN_DEGREE; + arcInfo.imgPos = {0, 0}; + arcInfo.imgSrc = nullptr; + DrawArc::GetInstance()->Draw(arcInfo, dirtyRect, arcStyle, opaScale, CapType::CAP_NONE); + + // draw right sector + arcInfo.center = {col3X, row2Y}; + arcInfo.startAngle = 0; + arcInfo.endAngle = SEMICIRCLE_IN_DEGREE; + DrawArc::GetInstance()->Draw(arcInfo, dirtyRect, arcStyle, opaScale, CapType::CAP_NONE); + + // draw top rectangle + Rect topRect(col2X, row1Y, col3X - 1, row2Y - 1); + OpacityType opa = DrawUtils::GetMixOpacity(opaScale, style.bgOpa_); + DrawUtils::GetInstance()->DrawColorArea(topRect, dirtyRect, style.bgColor_, opa); + + // draw bottom rectangle + Rect bottomRect(col2X + 1, row2Y, col3X - 1, row3Y); + DrawUtils::GetInstance()->DrawColorArea(bottomRect, dirtyRect, style.bgColor_, opa); +} + +void DrawRect::DrawRectRadiusWithoutBorderCon2(const Rect& rect, const Rect& dirtyRect, const Style& style, + OpacityType opaScale) +{ + int16_t radius = rect.GetWidth() / 2; + int16_t col1X = rect.GetLeft(); + int16_t col2X = rect.GetLeft() + radius - 1; + int16_t col3X = rect.GetRight(); + + int16_t row2Y = rect.GetTop() + radius - 1; + int16_t row3Y = rect.GetBottom() - radius + 1; + + Style arcStyle = style; + arcStyle.lineWidth_ = radius; + arcStyle.lineColor_ = style.bgColor_; + arcStyle.lineOpa_ = style.bgOpa_; + // draw top sector + ArcInfo arcInfo; + arcInfo.center = {col2X, row2Y}; + arcInfo.startAngle = THREE_QUARTER_IN_DEGREE; + arcInfo.endAngle = QUARTER_IN_DEGREE; + arcInfo.radius = radius; + arcInfo.imgPos = {0, 0}; + arcInfo.imgSrc = nullptr; + DrawArc::GetInstance()->Draw(arcInfo, dirtyRect, arcStyle, opaScale, CapType::CAP_NONE); + + // draw bottom sector + arcInfo.center = {col2X, row3Y}; + arcInfo.startAngle = QUARTER_IN_DEGREE; + arcInfo.endAngle = THREE_QUARTER_IN_DEGREE; + DrawArc::GetInstance()->Draw(arcInfo, dirtyRect, arcStyle, opaScale, CapType::CAP_NONE); + + // draw middle rectangle + Rect middleRect(col1X, row2Y + 1, col3X, row3Y - 1); + OpacityType opa = DrawUtils::GetMixOpacity(opaScale, style.bgOpa_); + DrawUtils::GetInstance()->DrawColorArea(middleRect, dirtyRect, style.bgColor_, opa); +} + +void DrawRect::DrawRectRadiusWithoutBorderCon3(const Rect& rect, const Rect& dirtyRect, const Style& style, + OpacityType opaScale) +{ + int16_t radius = rect.GetWidth() / 2; + int16_t col1X = rect.GetLeft() + radius - 1; + int16_t row1Y = rect.GetTop() + radius - 1; + + Style arcStyle = style; + arcStyle.lineWidth_ = radius; + arcStyle.lineColor_ = style.bgColor_; + arcStyle.lineOpa_ = style.bgOpa_; + // draw circle + ArcInfo arcInfo; + arcInfo.center = {col1X, row1Y}; + arcInfo.startAngle = 0; + arcInfo.endAngle = CIRCLE_IN_DEGREE; + arcInfo.radius = radius; + arcInfo.imgPos = {0, 0}; + arcInfo.imgSrc = nullptr; + DrawArc::GetInstance()->Draw(arcInfo, dirtyRect, arcStyle, opaScale, CapType::CAP_NONE); +} + +void DrawRect::DrawRectRadiusWithoutBorderCon4(const Rect& rect, const Rect& dirtyRect, const Style& style, + OpacityType opaScale) +{ + int16_t radius = style.borderRadius_; + int16_t col1X = rect.GetLeft(); + int16_t col2X = rect.GetLeft() + radius - 1; + int16_t col3X = rect.GetRight() - radius + 1; + int16_t col4X = rect.GetRight(); + + int16_t row1Y = rect.GetTop(); + int16_t row2Y = rect.GetTop() + radius - 1; + int16_t row3Y = rect.GetBottom() - radius + 1; + int16_t row4Y = rect.GetBottom(); + + OpacityType opa = DrawUtils::GetMixOpacity(opaScale, style.bgOpa_); + // draw top rectangle + Rect topRect(col2X, row1Y, col3X - 1, row2Y); + DrawUtils::GetInstance()->DrawColorArea(topRect, dirtyRect, style.bgColor_, opa); + + // draw middle rectangle + Rect middleRect(col1X, row2Y + 1, col4X, row3Y - 1); + DrawUtils::GetInstance()->DrawColorArea(middleRect, dirtyRect, style.bgColor_, opa); + + // draw bottom rectangle + Rect bottomRect(col2X + 1, row3Y, col3X - 1, row4Y); + DrawUtils::GetInstance()->DrawColorArea(bottomRect, dirtyRect, style.bgColor_, opa); + + Style arcStyle = style; + arcStyle.lineWidth_ = radius; + arcStyle.lineColor_ = style.bgColor_; + arcStyle.lineOpa_ = style.bgOpa_; + // top left sector + ArcInfo arcInfo; + arcInfo.center = {col2X, row2Y}; + arcInfo.startAngle = THREE_QUARTER_IN_DEGREE; + arcInfo.endAngle = CIRCLE_IN_DEGREE; + arcInfo.radius = radius; + arcInfo.imgPos = {0, 0}; + arcInfo.imgSrc = nullptr; + DrawArc::GetInstance()->Draw(arcInfo, dirtyRect, arcStyle, opaScale, CapType::CAP_NONE); + + // top right sector + arcInfo.center = {col3X, row2Y}; + arcInfo.startAngle = 0; + arcInfo.endAngle = QUARTER_IN_DEGREE; + DrawArc::GetInstance()->Draw(arcInfo, dirtyRect, arcStyle, opaScale, CapType::CAP_NONE); + + // bottom left sector + arcInfo.center = {col2X, row3Y}; + arcInfo.startAngle = SEMICIRCLE_IN_DEGREE; + arcInfo.endAngle = THREE_QUARTER_IN_DEGREE; + DrawArc::GetInstance()->Draw(arcInfo, dirtyRect, arcStyle, opaScale, CapType::CAP_NONE); + + // bottom right sector + arcInfo.center = {col3X, row3Y}; + arcInfo.startAngle = QUARTER_IN_DEGREE; + arcInfo.endAngle = SEMICIRCLE_IN_DEGREE; + DrawArc::GetInstance()->Draw(arcInfo, dirtyRect, arcStyle, opaScale, CapType::CAP_NONE); +} + +void DrawRect::DrawRectBorderWithoutRadius(const Rect& rect, const Rect& dirtyRect, const Style& style, + OpacityType opaScale) +{ + int16_t col1X = rect.GetLeft(); + int16_t col2X = rect.GetLeft() + style.borderWidth_ - 1; + int16_t col3X = rect.GetRight() - style.borderWidth_ + 1; + int16_t col4X = rect.GetRight(); + + int16_t row1Y = rect.GetTop(); + int16_t row2Y = rect.GetTop() + style.borderWidth_ - 1; + int16_t row3Y = rect.GetBottom() - style.borderWidth_ + 1; + int16_t row4Y = rect.GetBottom(); + + OpacityType opa = DrawUtils::GetMixOpacity(opaScale, style.borderOpa_); + // draw top border + Rect topRect(col1X, row1Y, col4X, row2Y); + DrawUtils::GetInstance()->DrawColorArea(topRect, dirtyRect, style.borderColor_, opa); + + // draw left border + Rect leftRect(col1X, row2Y + 1, col2X, row3Y - 1); + DrawUtils::GetInstance()->DrawColorArea(leftRect, dirtyRect, style.borderColor_, opa); + + OpacityType opaBg = DrawUtils::GetMixOpacity(opaScale, style.bgOpa_); + // draw middle rectangle + Rect middleRect(col2X + 1, row2Y + 1, col3X - 1, row3Y - 1); + DrawUtils::GetInstance()->DrawColorArea(middleRect, dirtyRect, style.bgColor_, opaBg); + + // draw right border + Rect rightRect(col3X, row2Y + 1, col4X, row3Y - 1); + DrawUtils::GetInstance()->DrawColorArea(rightRect, dirtyRect, style.borderColor_, opa); + + // draw bottom border + Rect bottomRect(col1X, row3Y, col4X, row4Y); + DrawUtils::GetInstance()->DrawColorArea(bottomRect, dirtyRect, style.borderColor_, opa); +} + +void DrawRect::DrawRectRadiusEqualBorder(const Rect& rect, const Rect& dirtyRect, const Style& style, + OpacityType opaScale) +{ + int16_t col1X = rect.GetLeft(); + int16_t col2X = rect.GetLeft() + style.borderRadius_ - 1; + int16_t col3X = rect.GetRight() - style.borderRadius_ + 1; + int16_t col4X = rect.GetRight(); + + int16_t row1Y = rect.GetTop(); + int16_t row2Y = rect.GetTop() + style.borderRadius_ - 1; + int16_t row3Y = rect.GetBottom() - style.borderRadius_ + 1; + int16_t row4Y = rect.GetBottom(); + + Style arcStyle = style; + arcStyle.lineWidth_ = style.borderWidth_; + arcStyle.lineColor_ = style.borderColor_; + arcStyle.lineOpa_ = style.borderOpa_; + // draw top left sector in border + ArcInfo arcInfo; + arcInfo.center = {col2X, row2Y}; + arcInfo.startAngle = THREE_QUARTER_IN_DEGREE; + arcInfo.endAngle = CIRCLE_IN_DEGREE; + arcInfo.radius = style.borderRadius_; + arcInfo.imgPos = {0, 0}; + arcInfo.imgSrc = nullptr; + DrawArc::GetInstance()->Draw(arcInfo, dirtyRect, arcStyle, opaScale, CapType::CAP_NONE); + + // draw top right sector in border + arcInfo.center = {col3X, row2Y}; + arcInfo.startAngle = 0; + arcInfo.endAngle = QUARTER_IN_DEGREE; + DrawArc::GetInstance()->Draw(arcInfo, dirtyRect, arcStyle, opaScale, CapType::CAP_NONE); + + // draw bottom left sector in border + arcInfo.center = {col2X, row3Y}; + arcInfo.startAngle = SEMICIRCLE_IN_DEGREE; + arcInfo.endAngle = THREE_QUARTER_IN_DEGREE; + DrawArc::GetInstance()->Draw(arcInfo, dirtyRect, arcStyle, opaScale, CapType::CAP_NONE); + + // draw bottom right sector in border + arcInfo.center = {col3X, row3Y}; + arcInfo.startAngle = QUARTER_IN_DEGREE; + arcInfo.endAngle = SEMICIRCLE_IN_DEGREE; + DrawArc::GetInstance()->Draw(arcInfo, dirtyRect, arcStyle, opaScale, CapType::CAP_NONE); + + OpacityType opa = DrawUtils::GetMixOpacity(opaScale, style.borderOpa_); + // draw top rectangle in border + Rect topRect(col2X, row1Y, col3X - 1, row2Y); + DrawUtils::GetInstance()->DrawColorArea(topRect, dirtyRect, style.borderColor_, opa); + + // draw left rectangle in border + Rect leftRect(col1X, row2Y + 1, col2X, row3Y - 1); + DrawUtils::GetInstance()->DrawColorArea(leftRect, dirtyRect, style.borderColor_, opa); + + OpacityType opaBg = DrawUtils::GetMixOpacity(opaScale, style.bgOpa_); + // draw middle rectangle + Rect middleRect(col2X + 1, row2Y + 1, col3X - 1, row3Y - 1); + DrawUtils::GetInstance()->DrawColorArea(middleRect, dirtyRect, style.bgColor_, opaBg); + + // draw right rectangle in border + Rect rightRect(col3X, row2Y + 1, col4X, row3Y - 1); + DrawUtils::GetInstance()->DrawColorArea(rightRect, dirtyRect, style.borderColor_, opa); + + // draw bottom rectangle in border + Rect bottomRect(col2X + 1, row3Y, col3X - 1, row4Y); + DrawUtils::GetInstance()->DrawColorArea(bottomRect, dirtyRect, style.borderColor_, opa); +} + +void DrawRect::DrawRectRadiusSmallThanBorder(const Rect& rect, const Rect& dirtyRect, const Style& style, + OpacityType opaScale) +{ + int16_t radiusCol1X = rect.GetLeft(); + int16_t radiusCol2X = rect.GetLeft() + style.borderRadius_ - 1; + int16_t radiusCol3X = rect.GetRight() - style.borderRadius_ + 1; + int16_t radiusCol4X = rect.GetRight(); + + int16_t radiusRow1Y = rect.GetTop(); + int16_t radiusRow2Y = rect.GetTop() + style.borderRadius_ - 1; + int16_t radiusRow3Y = rect.GetBottom() - style.borderRadius_ + 1; + int16_t radiusRow4Y = rect.GetBottom(); + + int16_t rectCol1X = radiusCol1X; + int16_t rectCol2X = rect.GetLeft() + style.borderWidth_ - 1; + int16_t rectCol3X = rect.GetRight() - style.borderWidth_ + 1; + int16_t rectCol4X = radiusCol4X; + + int16_t rectRow1Y = radiusRow2Y; + int16_t rectRow2Y = rect.GetTop() + style.borderWidth_ - 1; + int16_t rectRow3Y = rect.GetBottom() - style.borderWidth_ + 1; + + Style arcStyle = style; + arcStyle.lineWidth_ = style.borderWidth_; + arcStyle.lineColor_ = style.borderColor_; + arcStyle.lineOpa_ = style.borderOpa_; + // draw top left sector in border + ArcInfo arcInfo; + arcInfo.center = {radiusCol2X, radiusRow2Y}; + arcInfo.startAngle = THREE_QUARTER_IN_DEGREE; + arcInfo.endAngle = CIRCLE_IN_DEGREE; + arcInfo.radius = style.borderRadius_; + arcInfo.imgPos = {0, 0}; + arcInfo.imgSrc = nullptr; + DrawArc::GetInstance()->Draw(arcInfo, dirtyRect, arcStyle, opaScale, CapType::CAP_NONE); + + // draw top right sector in border + arcInfo.center = {radiusCol3X, radiusRow2Y}; + arcInfo.startAngle = 0; + arcInfo.endAngle = QUARTER_IN_DEGREE; + DrawArc::GetInstance()->Draw(arcInfo, dirtyRect, arcStyle, opaScale, CapType::CAP_NONE); + + // draw bottom left sector in border + arcInfo.center = {radiusCol2X, radiusRow3Y}; + arcInfo.startAngle = SEMICIRCLE_IN_DEGREE; + arcInfo.endAngle = THREE_QUARTER_IN_DEGREE; + DrawArc::GetInstance()->Draw(arcInfo, dirtyRect, arcStyle, opaScale, CapType::CAP_NONE); + + // draw bottom right sector in border + arcInfo.center = {radiusCol3X, radiusRow3Y}; + arcInfo.startAngle = QUARTER_IN_DEGREE; + arcInfo.endAngle = SEMICIRCLE_IN_DEGREE; + DrawArc::GetInstance()->Draw(arcInfo, dirtyRect, arcStyle, opaScale, CapType::CAP_NONE); + + OpacityType opa = DrawUtils::GetMixOpacity(opaScale, style.borderOpa_); + // draw top rectangle in border + Rect topRect(radiusCol2X, radiusRow1Y, radiusCol3X - 1, radiusRow2Y); + DrawUtils::GetInstance()->DrawColorArea(topRect, dirtyRect, style.borderColor_, opa); + Rect topRect2(rectCol1X, rectRow1Y + 1, rectCol4X, rectRow2Y); + DrawUtils::GetInstance()->DrawColorArea(topRect2, dirtyRect, style.borderColor_, opa); + + // draw left rectangle in border + Rect leftRect(rectCol1X, rectRow2Y + 1, rectCol2X, rectRow3Y - 1); + DrawUtils::GetInstance()->DrawColorArea(leftRect, dirtyRect, style.borderColor_, opa); + + OpacityType opaBg = DrawUtils::GetMixOpacity(opaScale, style.bgOpa_); + // draw middle rectangle + Rect middleRect(rectCol2X + 1, rectRow2Y + 1, rectCol3X - 1, rectRow3Y - 1); + DrawUtils::GetInstance()->DrawColorArea(middleRect, dirtyRect, style.bgColor_, opaBg); + + // draw right rectangle in border + Rect rightRect(rectCol3X, rectRow2Y + 1, rectCol4X, rectRow3Y - 1); + DrawUtils::GetInstance()->DrawColorArea(rightRect, dirtyRect, style.borderColor_, opa); + + // draw bottom rectangle in border + Rect bottomRect(radiusCol2X + 1, radiusRow3Y, radiusCol3X - 1, radiusRow4Y); + DrawUtils::GetInstance()->DrawColorArea(bottomRect, dirtyRect, style.borderColor_, opa); + Rect bottomRect2(rectCol1X, rectRow3Y, rectCol4X, radiusRow3Y - 1); + DrawUtils::GetInstance()->DrawColorArea(bottomRect2, dirtyRect, style.borderColor_, opa); +} + +void DrawRect::DrawRectRadiusBiggerThanBorder(const Rect& rect, const Rect& dirtyRect, const Style& style, + OpacityType opaScale) +{ + // 2 : half + if ((rect.GetWidth() > rect.GetHeight()) && (style.borderRadius_ >= rect.GetHeight() / 2)) { + DrawRectRadiusBiggerThanBorderCon1(rect, dirtyRect, style, opaScale); + } else if ((rect.GetWidth() < rect.GetHeight()) && (style.borderRadius_ >= rect.GetWidth() / 2)) { + DrawRectRadiusBiggerThanBorderCon2(rect, dirtyRect, style, opaScale); + } else if ((rect.GetWidth() == rect.GetHeight()) && (style.borderRadius_ >= rect.GetWidth() / 2)) { + DrawRectRadiusBiggerThanBorderCon3(rect, dirtyRect, style, opaScale); + } else { + DrawRectRadiusBiggerThanBorderCon4(rect, dirtyRect, style, opaScale); + } +} + +void DrawRect::DrawRectRadiusBiggerThanBorderCon1(const Rect& rect, const Rect& dirtyRect, const Style& style, + OpacityType opaScale) +{ + int16_t radius = rect.GetHeight() / 2; + int16_t borderWidth = style.borderWidth_; + int16_t col2X = rect.GetLeft() + radius - 1; + int16_t col3X = rect.GetRight() - radius + 1; + + int16_t row1Y = rect.GetTop(); + int16_t row2Y = rect.GetTop() + borderWidth - 1; + int16_t row3Y = rect.GetTop() + radius - 1; + int16_t row4Y = rect.GetBottom() - borderWidth + 1; + int16_t row5Y = rect.GetBottom(); + + Style arcStyle = style; + arcStyle.lineWidth_ = borderWidth; + arcStyle.lineColor_ = style.borderColor_; + arcStyle.lineOpa_ = style.borderOpa_; + // draw left arc in border + ArcInfo arcInfo; + arcInfo.center = {col2X, row3Y}; + arcInfo.startAngle = SEMICIRCLE_IN_DEGREE; + arcInfo.endAngle = CIRCLE_IN_DEGREE; + arcInfo.radius = radius; + arcInfo.imgPos = {0, 0}; + arcInfo.imgSrc = nullptr; + DrawArc::GetInstance()->Draw(arcInfo, dirtyRect, arcStyle, opaScale, CapType::CAP_NONE); + // draw right arc in border + arcInfo.center = {col3X, row3Y}; + arcInfo.startAngle = 0; + arcInfo.endAngle = SEMICIRCLE_IN_DEGREE; + DrawArc::GetInstance()->Draw(arcInfo, dirtyRect, arcStyle, opaScale, CapType::CAP_NONE); + + radius = radius - borderWidth; + arcStyle.lineWidth_ = radius; + arcStyle.lineColor_ = style.bgColor_; + arcStyle.lineOpa_ = style.bgOpa_; + + // draw left sector in rectangle + arcInfo.center = {col2X, row3Y}; + arcInfo.startAngle = SEMICIRCLE_IN_DEGREE; + arcInfo.endAngle = CIRCLE_IN_DEGREE; + arcInfo.radius = radius; + DrawArc::GetInstance()->Draw(arcInfo, dirtyRect, arcStyle, opaScale, CapType::CAP_NONE); + // draw right sector in rectangle + arcInfo.center = {col3X, row3Y}; + arcInfo.startAngle = 0; + arcInfo.endAngle = SEMICIRCLE_IN_DEGREE; + DrawArc::GetInstance()->Draw(arcInfo, dirtyRect, arcStyle, opaScale, CapType::CAP_NONE); + + OpacityType opa = DrawUtils::GetMixOpacity(opaScale, style.borderOpa_); + // top rectangle in border + Rect topBorderRect(col2X, row1Y, col3X - 1, row2Y); + DrawUtils::GetInstance()->DrawColorArea(topBorderRect, dirtyRect, style.borderColor_, opa); + OpacityType opaBg = DrawUtils::GetMixOpacity(opaScale, style.bgOpa_); + // middle rectangle inner + Rect middleInnerRect(col2X, row2Y + 1, col3X - 1, row3Y); + DrawUtils::GetInstance()->DrawColorArea(middleInnerRect, dirtyRect, style.bgColor_, opaBg); + Rect middleInnerRect2(col2X + 1, row3Y + 1, col3X - 1, row4Y - 1); + DrawUtils::GetInstance()->DrawColorArea(middleInnerRect2, dirtyRect, style.bgColor_, opaBg); + + // bottom rectangle in border + Rect bottomBorderRect(col2X + 1, row4Y, col3X - 1, row5Y); + DrawUtils::GetInstance()->DrawColorArea(bottomBorderRect, dirtyRect, style.borderColor_, opa); +} + +void DrawRect::DrawRectRadiusBiggerThanBorderCon2(const Rect& rect, const Rect& dirtyRect, const Style& style, + OpacityType opaScale) +{ + int16_t radius = rect.GetWidth() / 2; + int16_t borderWidth = style.borderWidth_; + int16_t col1X = rect.GetLeft(); + int16_t col2X = rect.GetLeft() + borderWidth - 1; + int16_t col3X = rect.GetLeft() + radius - 1; + int16_t col4X = rect.GetRight() - borderWidth + 1; + int16_t col5X = rect.GetRight(); + + int16_t row2Y = rect.GetTop() + radius - 1; + int16_t row3Y = rect.GetBottom() - radius + 1; + + Style arcStyle = style; + arcStyle.lineWidth_ = borderWidth; + arcStyle.lineColor_ = style.borderColor_; + arcStyle.lineOpa_ = style.borderOpa_; + // draw top arc in border + ArcInfo arcInfo; + arcInfo.center = {col3X, row2Y}; + arcInfo.startAngle = THREE_QUARTER_IN_DEGREE; + arcInfo.endAngle = QUARTER_IN_DEGREE; + arcInfo.radius = radius; + arcInfo.imgPos = {0, 0}; + arcInfo.imgSrc = nullptr; + DrawArc::GetInstance()->Draw(arcInfo, dirtyRect, arcStyle, opaScale, CapType::CAP_NONE); + // draw bottom arc in border + arcInfo.center = {col3X, row3Y}; + arcInfo.startAngle = QUARTER_IN_DEGREE; + arcInfo.endAngle = THREE_QUARTER_IN_DEGREE; + DrawArc::GetInstance()->Draw(arcInfo, dirtyRect, arcStyle, opaScale, CapType::CAP_NONE); + + radius = radius - borderWidth; + arcStyle.lineWidth_ = radius; + arcStyle.lineColor_ = style.bgColor_; + arcStyle.lineOpa_ = style.bgOpa_; + + // draw top sector in rectangle + arcInfo.center = {col3X, row2Y}; + arcInfo.startAngle = THREE_QUARTER_IN_DEGREE; + arcInfo.endAngle = QUARTER_IN_DEGREE; + arcInfo.radius = radius; + DrawArc::GetInstance()->Draw(arcInfo, dirtyRect, arcStyle, opaScale, CapType::CAP_NONE); + // draw bottom sector in rectangle + arcInfo.center = {col3X, row3Y}; + arcInfo.startAngle = QUARTER_IN_DEGREE; + arcInfo.endAngle = THREE_QUARTER_IN_DEGREE; + DrawArc::GetInstance()->Draw(arcInfo, dirtyRect, arcStyle, opaScale, CapType::CAP_NONE); + + OpacityType opa = DrawUtils::GetMixOpacity(opaScale, style.borderOpa_); + // left rectangle in border + Rect topBorderRect(col1X, row2Y + 1, col2X, row3Y - 1); + DrawUtils::GetInstance()->DrawColorArea(topBorderRect, dirtyRect, style.borderColor_, opa); + + OpacityType opaBg = DrawUtils::GetMixOpacity(opaScale, style.bgOpa_); + // middle rectangle inner + Rect middleInnerRect(col2X + 1, row2Y + 1, col4X - 1, row3Y - 1); + DrawUtils::GetInstance()->DrawColorArea(middleInnerRect, dirtyRect, style.bgColor_, opaBg); + + // right rectangle in border + Rect bottomBorderRect(col4X, row2Y + 1, col5X, row3Y - 1); + DrawUtils::GetInstance()->DrawColorArea(bottomBorderRect, dirtyRect, style.borderColor_, opa); +} + +void DrawRect::DrawRectRadiusBiggerThanBorderCon3(const Rect& rect, const Rect& dirtyRect, const Style& style, + OpacityType opaScale) +{ + int16_t radius = rect.GetWidth() / 2; + int16_t borderWidth = style.borderWidth_; + int16_t col2X = rect.GetLeft() + radius - 1; + int16_t row2Y = rect.GetTop() + radius - 1; + + Style arcStyle = style; + arcStyle.lineWidth_ = borderWidth; + arcStyle.lineColor_ = style.borderColor_; + arcStyle.lineOpa_ = style.borderOpa_; + // draw circle in border + ArcInfo arcInfo; + arcInfo.center = {col2X, row2Y}; + arcInfo.startAngle = 0; + arcInfo.endAngle = CIRCLE_IN_DEGREE; + arcInfo.radius = radius; + arcInfo.imgPos = {0, 0}; + arcInfo.imgSrc = nullptr; + DrawArc::GetInstance()->Draw(arcInfo, dirtyRect, arcStyle, opaScale, CapType::CAP_NONE); + + radius = radius - borderWidth; + arcStyle.lineWidth_ = radius; + arcStyle.lineColor_ = style.bgColor_; + arcStyle.lineOpa_ = style.bgOpa_; + + // draw circle in rectangle + arcInfo.center = {col2X, row2Y}; + arcInfo.startAngle = 0; + arcInfo.endAngle = CIRCLE_IN_DEGREE; + arcInfo.radius = radius; + DrawArc::GetInstance()->Draw(arcInfo, dirtyRect, arcStyle, opaScale, CapType::CAP_NONE); +} + +void DrawRect::DrawRectRadiusBiggerThanBorderCon4(const Rect& rect, const Rect& dirtyRect, const Style& style, + OpacityType opaScale) +{ + int16_t radius = style.borderRadius_; + int16_t borderWidth = style.borderWidth_; + int16_t col1X = rect.GetLeft(); + int16_t col2X = rect.GetLeft() + borderWidth - 1; + int16_t col3X = rect.GetLeft() + radius - 1; + int16_t col4X = rect.GetRight() - radius + 1; + int16_t col5X = rect.GetRight() - borderWidth + 1; + int16_t col6X = rect.GetRight(); + + int16_t row1Y = rect.GetTop(); + int16_t row2Y = rect.GetTop() + borderWidth - 1; + int16_t row3Y = rect.GetTop() + radius - 1; + int16_t row4Y = rect.GetBottom() - radius + 1; + int16_t row5Y = rect.GetBottom() - borderWidth + 1; + int16_t row6Y = rect.GetBottom(); + + Style arcStyle = style; + arcStyle.lineWidth_ = borderWidth; + arcStyle.lineColor_ = style.borderColor_; + arcStyle.lineOpa_ = style.borderOpa_; + + // draw top left arc in border + ArcInfo arcInfo; + arcInfo.center = {col3X, row3Y}; + arcInfo.startAngle = THREE_QUARTER_IN_DEGREE; + arcInfo.endAngle = CIRCLE_IN_DEGREE; + arcInfo.radius = radius; + arcInfo.imgPos = {0, 0}; + arcInfo.imgSrc = nullptr; + DrawArc::GetInstance()->Draw(arcInfo, dirtyRect, arcStyle, opaScale, CapType::CAP_NONE); + // draw top right arc in border + arcInfo.center = {col4X, row3Y}; + arcInfo.startAngle = 0; + arcInfo.endAngle = QUARTER_IN_DEGREE; + DrawArc::GetInstance()->Draw(arcInfo, dirtyRect, arcStyle, opaScale, CapType::CAP_NONE); + // draw bottom left arc in border + arcInfo.center = {col3X, row4Y}; + arcInfo.startAngle = SEMICIRCLE_IN_DEGREE; + arcInfo.endAngle = THREE_QUARTER_IN_DEGREE; + DrawArc::GetInstance()->Draw(arcInfo, dirtyRect, arcStyle, opaScale, CapType::CAP_NONE); + // draw bottom right arc in border + arcInfo.center = {col4X, row4Y}; + arcInfo.startAngle = QUARTER_IN_DEGREE; + arcInfo.endAngle = SEMICIRCLE_IN_DEGREE; + DrawArc::GetInstance()->Draw(arcInfo, dirtyRect, arcStyle, opaScale, CapType::CAP_NONE); + + radius = radius - borderWidth; + arcStyle.lineWidth_ = radius; + arcStyle.lineColor_ = style.bgColor_; + arcStyle.lineOpa_ = style.bgOpa_; + + // draw top left sector in rectangle + arcInfo.center = {col3X, row3Y}; + arcInfo.startAngle = THREE_QUARTER_IN_DEGREE; + arcInfo.endAngle = CIRCLE_IN_DEGREE; + arcInfo.radius = radius; + DrawArc::GetInstance()->Draw(arcInfo, dirtyRect, arcStyle, opaScale, CapType::CAP_NONE); + // draw top right sector in rectangle + arcInfo.center = {col4X, row3Y}; + arcInfo.startAngle = 0; + arcInfo.endAngle = QUARTER_IN_DEGREE; + DrawArc::GetInstance()->Draw(arcInfo, dirtyRect, arcStyle, opaScale, CapType::CAP_NONE); + // draw bottom left sector in rectangle + arcInfo.center = {col3X, row4Y}; + arcInfo.startAngle = SEMICIRCLE_IN_DEGREE; + arcInfo.endAngle = THREE_QUARTER_IN_DEGREE; + DrawArc::GetInstance()->Draw(arcInfo, dirtyRect, arcStyle, opaScale, CapType::CAP_NONE); + // draw bottom right sector in rectangle + arcInfo.center = {col4X, row4Y}; + arcInfo.startAngle = QUARTER_IN_DEGREE; + arcInfo.endAngle = SEMICIRCLE_IN_DEGREE; + DrawArc::GetInstance()->Draw(arcInfo, dirtyRect, arcStyle, opaScale, CapType::CAP_NONE); + + OpacityType opa = DrawUtils::GetMixOpacity(opaScale, style.borderOpa_); + // top rectangle in border + Rect topBorderRect(col3X, row1Y, col4X - 1, row2Y); + DrawUtils::GetInstance()->DrawColorArea(topBorderRect, dirtyRect, style.borderColor_, opa); + + OpacityType opaBg = DrawUtils::GetMixOpacity(opaScale, style.bgOpa_); + // top rectangle inner + Rect topInnerRect(col3X, row2Y + 1, col4X - 1, row3Y); + DrawUtils::GetInstance()->DrawColorArea(topInnerRect, dirtyRect, style.bgColor_, opaBg); + + // left rectangle in border + Rect leftBorderRect(col1X, row3Y + 1, col2X, row4Y - 1); + DrawUtils::GetInstance()->DrawColorArea(leftBorderRect, dirtyRect, style.borderColor_, opa); + + // middle rectangle inner + Rect middleInnerRect(col2X + 1, row3Y + 1, col5X - 1, row4Y - 1); + DrawUtils::GetInstance()->DrawColorArea(middleInnerRect, dirtyRect, style.bgColor_, opaBg); + + // right rectangle in border + Rect rightBorderRect(col5X, row3Y + 1, col6X, row4Y - 1); + DrawUtils::GetInstance()->DrawColorArea(rightBorderRect, dirtyRect, style.borderColor_, opa); + + // bottom rectangle inner + Rect bottomInnerRect(col3X + 1, row4Y, col4X - 1, row5Y - 1); + DrawUtils::GetInstance()->DrawColorArea(bottomInnerRect, dirtyRect, style.bgColor_, opaBg); + + // bottom rectangle in border + Rect bottomBorderRect(col3X + 1, row5Y, col4X - 1, row6Y); + DrawUtils::GetInstance()->DrawColorArea(bottomBorderRect, dirtyRect, style.borderColor_, opa); +} +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/draw/draw_rect.h b/frameworks/draw/draw_rect.h new file mode 100755 index 0000000..8ee480b --- /dev/null +++ b/frameworks/draw/draw_rect.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef GRAPHIC_LITE_DRAW_RECT_H +#define GRAPHIC_LITE_DRAW_RECT_H + +#include "components/ui_view.h" + +namespace OHOS { +/** @brief Class for drawing rectangle. */ +class DrawRect : public HeapBase { +public: + DrawRect() {}; + ~DrawRect() {}; + + static void Draw(const Rect& rect, const Rect& dirtyRect, const Style& style, OpacityType opaScale); + +private: + static void DrawRectRadiusWithoutBorder(const Rect& rect, const Rect& dirtyRect, const Style& style, + OpacityType opaScale); + static void DrawRectBorderWithoutRadius(const Rect& rect, const Rect& dirtyRect, const Style& style, + OpacityType opaScale); + static void DrawRectRadiusEqualBorder(const Rect& rect, const Rect& dirtyRect, const Style& style, + OpacityType opaScale); + static void DrawRectRadiusSmallThanBorder(const Rect& rect, const Rect& dirtyRect, const Style& style, + OpacityType opaScale); + static void DrawRectRadiusBiggerThanBorder(const Rect& rect, const Rect& dirtyRect, const Style& style, + OpacityType opaScale); + + static void DrawRectRadiusWithoutBorderCon1(const Rect& rect, const Rect& dirtyRect, const Style& style, + OpacityType opaScale); + static void DrawRectRadiusWithoutBorderCon2(const Rect& rect, const Rect& dirtyRect, const Style& style, + OpacityType opaScale); + static void DrawRectRadiusWithoutBorderCon3(const Rect& rect, const Rect& dirtyRect, const Style& style, + OpacityType opaScale); + static void DrawRectRadiusWithoutBorderCon4(const Rect& rect, const Rect& dirtyRect, const Style& style, + OpacityType opaScale); + + static void DrawRectRadiusBiggerThanBorderCon1(const Rect& rect, const Rect& dirtyRect, const Style& style, + OpacityType opaScale); + static void DrawRectRadiusBiggerThanBorderCon2(const Rect& rect, const Rect& dirtyRect, const Style& style, + OpacityType opaScale); + static void DrawRectRadiusBiggerThanBorderCon3(const Rect& rect, const Rect& dirtyRect, const Style& style, + OpacityType opaScale); + static void DrawRectRadiusBiggerThanBorderCon4(const Rect& rect, const Rect& dirtyRect, const Style& style, + OpacityType opaScale); +}; +} // namespace OHOS +#endif // GRAPHIC_LITE_DRAW_RECT_H diff --git a/frameworks/draw/draw_triangle.cpp b/frameworks/draw/draw_triangle.cpp new file mode 100755 index 0000000..950cb5f --- /dev/null +++ b/frameworks/draw/draw_triangle.cpp @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "draw/draw_triangle.h" +#include "draw/draw_utils.h" + +namespace OHOS { +void DrawTriangle::Draw(const Point* points, uint8_t count, const Rect& mask, const ColorType& color, OpacityType opa) +{ + if ((points == nullptr) || (count != VERTEX_NUM)) { + return; + } + // sort vertex according to y axis + Point p1 = points[0]; // 0: point index + Point p2 = points[1]; // 1: point index + Point p3 = points[2]; // 2: point index + // return if vertexs are invalid. + if ((p1.x == p2.x) && ((p1.y == p2.y) || (p1.x == p3.x))) { + return; + } + if ((p2.x == p3.x) && (p2.y == p3.y)) { + return; + } + if (((p1.x == p3.x) || (p1.y == p2.y)) && (p1.y == p3.y)) { + return; + } + SortVertexs(p1, p2, p3); + Edge edge1 = InitEdge(p1, p2); + Edge edge2 = InitEdge(p1, p3); + Rect area; + int16_t lastY = p1.y; + + while (edge1.curPoint.y <= p3.y) { + // change edge1 from p1-p2 to p2-p3 + if (edge1.curPoint.y == p2.y) { + edge1 = InitEdge(p2, p3); + if (edge1.dPoint.y == 0) { + return; + } + } + + area.SetLeft(MATH_MIN(edge1.curPoint.x, edge2.curPoint.x)); + area.SetRight(MATH_MAX(edge1.curPoint.x, edge2.curPoint.x)); + area.SetTop(MATH_MIN(edge1.curPoint.y, edge2.curPoint.y)); + area.SetBottom(MATH_MAX(edge1.curPoint.y, edge2.curPoint.y)); + DrawUtils::GetInstance()->DrawColorArea(area, mask, color, opa); + + while (edge1.curPoint.y == lastY) { + // use Bresenham algorithm to get next point on edge1 + StepToNextPointOnEdge(edge1); + } + while (edge2.curPoint.y == lastY) { + // use Bresenham algorithm to get next point on edge2 + StepToNextPointOnEdge(edge2); + } + lastY = edge1.curPoint.y; + } +} + +void DrawTriangle::SortVertexs(Point& p1, Point& p2, Point& p3) +{ + SortPoint(p1, p2); + SortPoint(p2, p3); + SortPoint(p1, p2); +} + +void DrawTriangle::SortPoint(Point& p1, Point& p2) +{ + Point temp; + if (p1.y > p2.y) { + temp = p1; + p1 = p2; + p2 = temp; + } +} + +void DrawTriangle::StepToNextPointOnEdge(Edge& edge) +{ + if (edge.dPoint.x > edge.dPoint.y) { + edge.curPoint.x += edge.uPoint.x; + edge.eps += edge.dPoint.y; + if ((edge.eps << 1) >= edge.dPoint.x) { + edge.curPoint.y += edge.uPoint.y; + edge.eps -= edge.dPoint.x; + } + } else { + edge.curPoint.y += edge.uPoint.y; + edge.eps += edge.dPoint.x; + if ((edge.eps << 1) >= edge.dPoint.y) { + edge.curPoint.x += edge.uPoint.x; + edge.eps -= edge.dPoint.y; + } + } +} + +DrawTriangle::Edge DrawTriangle::InitEdge(const Point& startP, const Point& endP) +{ + Edge edge = { {0, 0}, {0, 0}, {0, 0}, 0 }; + edge.curPoint = startP; + edge.dPoint.x = startP.x - endP.x; + edge.dPoint.y = startP.y - endP.y; + edge.uPoint.x = (edge.dPoint.x < 0) ? 1 : -1; + edge.uPoint.y = (edge.dPoint.y < 0) ? 1 : -1; + edge.eps = 0; + edge.dPoint.x = MATH_ABS(edge.dPoint.x); + edge.dPoint.y = MATH_ABS(edge.dPoint.y); + return edge; +} +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/draw/draw_triangle.h b/frameworks/draw/draw_triangle.h new file mode 100755 index 0000000..e00cbb9 --- /dev/null +++ b/frameworks/draw/draw_triangle.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef GRAPHIC_LITE_DRAW_TRIANGLE_H +#define GRAPHIC_LITE_DRAW_TRIANGLE_H + +#include "color.h" +#include "geometry2d.h" + +namespace OHOS { +class DrawTriangle : public HeapBase { +public: + static void Draw(const Point* points, uint8_t count, const Rect& mask, const ColorType& color, OpacityType opa); + + struct Edge { + Point curPoint; + Point dPoint; + Point uPoint; + int16_t eps; + }; + + static void SortVertexs(Point& p1, Point& p2, Point& p3); + + static void SortPoint(Point& p1, Point& p2); + + static void StepToNextPointOnEdge(Edge& edge); + + static Edge InitEdge(const Point& startP, const Point& endP); +private: + static constexpr uint8_t VERTEX_NUM = 3; +}; +} // namespace OHOS +#endif // GRAPHIC_LITE_DRAW_TRIANGLE_H diff --git a/frameworks/draw/draw_utils.cpp b/frameworks/draw/draw_utils.cpp new file mode 100644 index 0000000..b19a59d --- /dev/null +++ b/frameworks/draw/draw_utils.cpp @@ -0,0 +1,1643 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "draw/draw_utils.h" +#include "color.h" +#include "draw/draw_triangle.h" +#include "font/ui_font.h" +#include "font/ui_font_header.h" +#include "graphic_log.h" +#include "graphic_math.h" +#include "graphic_performance.h" +#include "securec.h" + +#ifdef ARM_NEON_OPT +#include "graphic_neon_pipeline.h" +#include "graphic_neon_utils.h" +#endif + +#if ENABLE_GFX_ENGINES +#include "hals/gfx_engines.h" +#endif + +#ifdef _LITEOS +#include "arm_math.h" +#endif + +namespace OHOS { +// Preprocess operation for draw +#define DRAW_UTILS_PREPROCESS(opa) \ + if ((opa) == OPA_TRANSPARENT) { \ + return; \ + } \ + uint8_t* screenBuffer = ScreenDeviceProxy::GetInstance()->GetBuffer(); \ + if (screenBuffer == nullptr) { \ + return; \ + } \ + ColorMode bufferMode = ScreenDeviceProxy::GetInstance()->GetBufferMode(); \ + uint8_t bufferPxSize = GetByteSizeByColorMode(bufferMode); \ + uint16_t screenBufferWidth = ScreenDeviceProxy::GetInstance()->GetBufferWidth(); \ + Rect bufferRect = ScreenDeviceProxy::GetInstance()->GetBufferRect(); + +/* cover mode, src alpha is 255 */ +#define COLOR_FILL_COVER(d, dm, r2, g2, b2, sm) \ + if ((dm) == ARGB8888) { \ + reinterpret_cast(d)->alpha = OPA_OPAQUE; \ + if (sm == RGB565) { \ + reinterpret_cast(d)->red = (r2) << 3; \ + reinterpret_cast(d)->green = (g2) << 2; \ + reinterpret_cast(d)->blue = (b2) << 3; \ + } else { \ + reinterpret_cast(d)->red = (r2); \ + reinterpret_cast(d)->green = (g2); \ + reinterpret_cast(d)->blue = (b2); \ + } \ + } else if ((dm) == RGB888) { \ + if (sm == RGB565) { \ + reinterpret_cast(d)->red = (r2) << 3; \ + reinterpret_cast(d)->green = (g2) << 2; \ + reinterpret_cast(d)->blue = (b2) << 3; \ + } else { \ + reinterpret_cast(d)->red = (r2); \ + reinterpret_cast(d)->green = (g2); \ + reinterpret_cast(d)->blue = (b2); \ + } \ + } else if ((dm) == RGB565) { \ + if ((sm) == ARGB8888 || (sm) == RGB888) { \ + reinterpret_cast(d)->red = (r2) >> 3; \ + reinterpret_cast(d)->green = (g2) >> 2; \ + reinterpret_cast(d)->blue = (b2) >> 3; \ + } else { \ + reinterpret_cast(d)->red = (r2); \ + reinterpret_cast(d)->green = (g2); \ + reinterpret_cast(d)->blue = (b2); \ + } \ + } else { \ + ASSERT(0); \ + } + +#define COLOR_BLEND_RGBA(r1, g1, b1, a1, r2, g2, b2, a2) \ + const float A1 = static_cast(a1) / OPA_OPAQUE; \ + const float A2 = static_cast(a2) / OPA_OPAQUE; \ + const float a = 1 - (1 - A1) * (1 - A2); \ + (r1) = (A2 * (r2) + (1 - A2) * A1 * (r1)) / a; \ + (g1) = (A2 * (g2) + (1 - A2) * A1 * (g1)) / a; \ + (b1) = (A2 * (b2) + (1 - A2) * A1 * (b1)) / a; \ + (a1) = a * OPA_OPAQUE; + +#define COLOR_BLEND_RGB(r1, g1, b1, r2, g2, b2, a2) \ + (r1) = (((r2) * (a2)) / OPA_OPAQUE) + (((r1) * (OPA_OPAQUE - (a2))) / OPA_OPAQUE); \ + (g1) = (((g2) * (a2)) / OPA_OPAQUE) + (((g1) * (OPA_OPAQUE - (a2))) / OPA_OPAQUE); \ + (b1) = (((b2) * (a2)) / OPA_OPAQUE) + (((b1) * (OPA_OPAQUE - (a2))) / OPA_OPAQUE); + +// 565 +#define COLOR_FILL_BLEND(d, dm, s, sm, a) \ + if ((dm) == ARGB8888) { \ + Color32* p = reinterpret_cast(d); \ + if ((sm) == ARGB8888) { \ + Color32* sTmp = reinterpret_cast(s); \ + uint8_t alpha = (sTmp->alpha * (a)) / OPA_OPAQUE; \ + COLOR_BLEND_RGBA(p->red, p->green, p->blue, p->alpha, sTmp->red, sTmp->green, sTmp->blue, alpha); \ + } else if ((sm) == RGB888) { \ + Color24* sTmp = reinterpret_cast(s); \ + COLOR_BLEND_RGBA(p->red, p->green, p->blue, p->alpha, sTmp->red, sTmp->green, sTmp->blue, a); \ + } else if ((sm) == RGB565) { \ + Color16* sTmp = reinterpret_cast(s); \ + COLOR_BLEND_RGBA(p->red, p->green, p->blue, p->alpha, (sTmp->red) << 3, (sTmp->green) << 2, \ + (sTmp->blue) << 3, a); \ + } \ + } else if ((dm) == RGB888) { \ + Color24* p = reinterpret_cast(d); \ + if ((sm) == ARGB8888) { \ + Color32* sTmp = reinterpret_cast(s); \ + uint8_t alpha = (sTmp->alpha * (a)) / OPA_OPAQUE; \ + COLOR_BLEND_RGB(p->red, p->green, p->blue, sTmp->red, sTmp->green, sTmp->blue, alpha); \ + } else if ((sm) == RGB888) { \ + Color24* sTmp = reinterpret_cast(s); \ + COLOR_BLEND_RGB(p->red, p->green, p->blue, sTmp->red, sTmp->green, sTmp->blue, a); \ + } else if ((sm) == RGB565) { \ + Color16* sTmp = reinterpret_cast(s); \ + COLOR_BLEND_RGB(p->red, p->green, p->blue, (sTmp->red) << 3, (sTmp->green) << 2, (sTmp->blue) << 3, a); \ + } \ + } else if ((dm) == RGB565) { \ + Color16* p = reinterpret_cast(d); \ + if ((sm) == ARGB8888) { \ + Color32* sTmp = reinterpret_cast(s); \ + uint8_t alpha = (sTmp->alpha * (a)) / OPA_OPAQUE; \ + COLOR_BLEND_RGB(p->red, p->green, p->blue, (sTmp->red) >> 3, (sTmp->green) >> 2, (sTmp->blue) >> 3, \ + alpha); \ + } else if ((sm) == RGB888) { \ + Color24* sTmp = reinterpret_cast(s); \ + COLOR_BLEND_RGB(p->red, p->green, p->blue, (sTmp->red) >> 3, (sTmp->green) >> 2, (sTmp->blue) >> 3, a); \ + } else if ((sm) == RGB565) { \ + Color16* sTmp = reinterpret_cast(s); \ + COLOR_BLEND_RGB(p->red, p->green, p->blue, sTmp->red, sTmp->green, sTmp->blue, a); \ + } \ + } else { \ + ASSERT(0); \ + } + +#ifdef VERSION_STANDARD +const int16_t HARDWARE_ACC_SIZE_LIMIT = 50 * 50; +#endif + +namespace { +static constexpr uint8_t OPACITY_STEP_A1 = 255; +static constexpr uint8_t OPACITY_STEP_A2 = 85; +static constexpr uint8_t OPACITY_STEP_A4 = 17; +} // namespace + +TriangleEdge::TriangleEdge(int16_t x1, int16_t y1, int16_t x2, int16_t y2) +{ + curX = static_cast(x1); + curY = static_cast(y1); + du = static_cast(x2 - x1); + dv = static_cast(y2 - y1); +} + +TriangleEdge::~TriangleEdge() {} + +void DrawUtils::DrawColorAreaBySides(const Rect& mask, + const ColorType& color, + OpacityType opa, + const EdgeSides& sides) const +{ + Rect area(sides.left, sides.top, sides.right, sides.bottom); + DrawUtils::GetInstance()->DrawColorArea(area, mask, color, opa); +} + +void DrawUtils::DrawColorArea(const Rect& area, const Rect& mask, const ColorType& color, OpacityType opa) const +{ + DRAW_UTILS_PREPROCESS(opa); + Rect maskedArea; + if (!maskedArea.Intersect(area, mask)) { + return; + } +#if !ENABLE_WINDOW + maskedArea.SetRect(maskedArea.GetLeft() - bufferRect.GetLeft(), maskedArea.GetTop() - bufferRect.GetTop(), + maskedArea.GetRight() - bufferRect.GetLeft(), maskedArea.GetBottom() - bufferRect.GetTop()); +#endif +#if ENABLE_HARDWARE_ACCELERATION + if (ScreenDeviceProxy::GetInstance()->HardwareFill(maskedArea, Color::ColorTo32(color), opa, screenBuffer, + screenBufferWidth * bufferPxSize, bufferMode)) { + return; + } +#endif +#if ENABLE_GFX_ENGINES + if (FillAreaWithHardware(maskedArea, color, opa)) { + return; + } +#endif + FillAreaWithSoftWare(maskedArea, screenBuffer, bufferMode, bufferPxSize, screenBufferWidth, color, opa); +} + +uint8_t DrawUtils::GetPxSizeByColorMode(uint8_t colorMode) +{ + switch (colorMode) { + case ARGB8888: + return 32; // 32: 32 bit + case RGB888: + return 24; // 24: 24 bit + case RGB565: + case ARGB1555: + case ARGB4444: + return 16; // 16: 16 bit + case L1: + case A1: + return 1; // 1: 1 bit + case L2: + case A2: + return 2; // 2: 2 bit + case L4: + case A4: + return 4; // 4: 4 bit + case L8: + case A8: + return 8; // 8: 8 bit + default: + return 0; + } +} + +uint8_t DrawUtils::GetByteSizeByColorMode(uint8_t colorMode) +{ + switch (colorMode) { + case ARGB8888: + return 4; // 4: 4 Byte + case RGB888: + return 3; // 3: 3 Byte + case RGB565: + case ARGB1555: + case ARGB4444: + return 2; // 2: 2 Byte + default: + return 0; + } +} + +uint8_t DrawUtils::GetPxSizeByImageInfo(ImageInfo imageInfo) +{ + if ((imageInfo.header.width == 0) || (imageInfo.header.height == 0)) { + return 0; + } + /* 3 : when change byte to single pixel, the buffer should multiply by 8, equal to shift left 3 bits. */ + uint8_t pxSize = (imageInfo.dataSize / (imageInfo.header.width * imageInfo.header.height)) << 3; + return pxSize; +} + +void DrawUtils::DrawPixel(int16_t x, int16_t y, const Rect& mask, const ColorType& color, OpacityType opa) const +{ + if ((x < mask.GetLeft()) || (x > mask.GetRight()) || (y < mask.GetTop()) || (y > mask.GetBottom())) { + return; + } + + DRAW_UTILS_PREPROCESS(opa); + +#if !ENABLE_WINDOW + x -= bufferRect.GetLeft(); + y -= bufferRect.GetTop(); +#endif + + Color32 fillColor; + fillColor.full = Color::ColorTo32(color); + + screenBuffer += (y * screenBufferWidth + x) * bufferPxSize; + COLOR_FILL_BLEND(screenBuffer, bufferMode, &fillColor, ARGB8888, opa); +} + +void DrawUtils::DrawLetter(const LabelLetterInfo& letterInfo) const +{ + OpacityType opa = letterInfo.opa; + Color32 fillColor; + fillColor.full = Color::ColorTo32(letterInfo.color); + + DRAW_UTILS_PREPROCESS(opa); + UIFont* fontEngine = UIFont::GetInstance(); + FontHeader head; + GlyphNode node; + if (fontEngine->GetCurrentFontHeader(head) != 0) { + return; + } + + const uint8_t* fontMap = fontEngine->GetBitmap(letterInfo.letter, node, letterInfo.shapingId); + if (fontMap == nullptr) { + return; + } + uint16_t letterW = node.cols; + uint16_t letterH = node.rows; + uint8_t opacityMask; + int16_t posX; + int16_t posY = letterInfo.pos.y + letterInfo.fontSize - node.top - letterInfo.offsetY; + uint8_t fontWeight = fontEngine->GetFontWeight(letterInfo.fontId); + uint8_t colorMode = 0; + uint8_t opacityStep = 1; + switch (fontWeight) { + case FONT_WEIGHT_1: + opacityStep = OPACITY_STEP_A1; + opacityMask = 0x01; + colorMode = A1; + break; + case FONT_WEIGHT_2: + opacityStep = OPACITY_STEP_A2; + opacityMask = 0x03; + colorMode = A2; + break; + case FONT_WEIGHT_4: + opacityStep = OPACITY_STEP_A4; + opacityMask = 0x0F; + colorMode = A4; + break; + case FONT_WEIGHT_8: + opacityMask = 0xFF; + colorMode = A8; + break; + default: + return; + } + + if (letterInfo.direct == TEXT_DIRECT_RTL) { + /* RTL */ + posX = letterInfo.pos.x - node.advance + node.left + letterInfo.offsetX; + } else { + /* LTR */ + posX = letterInfo.pos.x + node.left + letterInfo.offsetX; + } + + if ((posX + letterW < letterInfo.mask.GetLeft()) || (posX > letterInfo.mask.GetRight()) || + (posY + letterH < letterInfo.mask.GetTop()) || (posY > letterInfo.mask.GetBottom())) { + return; + } + + uint16_t rowStart = (posY >= letterInfo.mask.GetTop()) ? 0 : (letterInfo.mask.GetTop() - posY); + uint16_t rowEnd = + (posY + letterH <= letterInfo.mask.GetBottom()) ? letterH : (letterInfo.mask.GetBottom() - posY + 1); + uint16_t colStart = (posX >= letterInfo.mask.GetLeft()) ? 0 : (letterInfo.mask.GetLeft() - posX); + uint16_t colEnd = + (posX + letterW <= letterInfo.mask.GetRight()) ? letterW : (letterInfo.mask.GetRight() - posX + 1); + + uint8_t letterWidthInByte = (letterW * fontWeight) >> SHIFT_3; + if ((letterW * fontWeight) & 0x7) { + letterWidthInByte++; + } + +#if ENABLE_WINDOW + int16_t dstPosX = posX + colStart; + int16_t dstPosY = posY + rowStart; +#else + int16_t dstPosX = posX + colStart - bufferRect.GetLeft(); + int16_t dstPosY = posY + rowStart - bufferRect.GetTop(); +#endif + +#if ENABLE_HARDWARE_ACCELERATION && ENABLE_HARDWARE_ACCELERATION_FOR_TEXT + Rect srcRect(colStart, rowStart, colEnd - 1, rowEnd - 1); + if (ScreenDeviceProxy::GetInstance()->HardwareBlend(fontMap, srcRect, letterWidthInByte, letterH, + static_cast(colorMode), + Color::ColorTo32(letterInfo.color), opa, reinterpret_cast(screenBuffer), + screenBufferWidth * bufferPxSize, bufferMode, dstPosX, dstPosY)) { + return; + } +#endif + + screenBuffer += ((dstPosY * screenBufferWidth) + dstPosX) * bufferPxSize; + fontMap += (rowStart * letterWidthInByte) + ((colStart * fontWeight) >> SHIFT_3); + + uint8_t offsetInFont = (colStart * fontWeight) % FONT_WEIGHT_8; + int16_t temp = (colEnd - colStart) * fontWeight - FONT_WEIGHT_8 + offsetInFont; + if (temp < 0) { + temp = 0; + } + int16_t validWidthInByte = temp / FONT_WEIGHT_8 + 1; + if (temp % FONT_WEIGHT_8 != 0) { + validWidthInByte++; + } + for (int16_t i = rowStart; i < rowEnd; i++) { + int16_t col = colStart; + uint8_t tempOffset = offsetInFont; + uint8_t tempFontByte = (*fontMap++) >> offsetInFont; + while (col < colEnd) { + while ((tempOffset < FONT_WEIGHT_8) && (col < colEnd)) { + uint8_t validOpacity = tempFontByte & opacityMask; + if (validOpacity != 0) { + validOpacity *= opacityStep; + if (opa != OPA_OPAQUE) { + validOpacity = + static_cast((static_cast(validOpacity) * opa) >> FONT_WEIGHT_8); + } + COLOR_FILL_BLEND(screenBuffer, bufferMode, &fillColor, ARGB8888, validOpacity); + } + screenBuffer += bufferPxSize; + tempFontByte = tempFontByte >> fontWeight; + tempOffset += fontWeight; + col++; + } + tempOffset = 0; + tempFontByte = *(fontMap++); + } + fontMap += (letterWidthInByte)-validWidthInByte - 1; + screenBuffer += (screenBufferWidth - (colEnd - colStart)) * bufferPxSize; + } +} + +void DrawUtils::DrawImage(const Rect& area, + const Rect& mask, + const uint8_t* image, + OpacityType opa, + uint8_t pxByteSize) const +{ + if (image == nullptr) { + return; + } + DRAW_UTILS_PREPROCESS(opa); + Rect maskedArea; + Rect originMaskedArea; + if (!originMaskedArea.Intersect(area, mask)) { + return; + } +#if ENABLE_WINDOW + maskedArea = originMaskedArea; +#else + maskedArea.SetRect( + originMaskedArea.GetLeft() - bufferRect.GetLeft(), originMaskedArea.GetTop() - bufferRect.GetTop(), + originMaskedArea.GetRight() - bufferRect.GetLeft(), originMaskedArea.GetBottom() - bufferRect.GetTop()); +#endif + int16_t mapWidth = area.GetWidth(); + int16_t imageX = originMaskedArea.GetLeft() - area.GetLeft(); + int16_t imageY = originMaskedArea.GetTop() - area.GetTop(); + + ColorMode srcMode; + if (pxByteSize == static_cast(PixelType::IMG_RGB888)) { + srcMode = RGB888; + } else if (pxByteSize == static_cast(PixelType::IMG_RGB565)) { + srcMode = RGB565; + } else if (pxByteSize == static_cast(PixelType::IMG_ARGB8888)) { + srcMode = ARGB8888; + } else { + GRAPHIC_LOGE("DrawUtils::DrawImage image format err\n"); + return; + } +#if ENABLE_HARDWARE_ACCELERATION + Rect srcRect(imageX, imageY, imageX + maskedArea.GetWidth() - 1, imageY + maskedArea.GetHeight() - 1); + if (ScreenDeviceProxy::GetInstance()->HardwareBlend(image, srcRect, mapWidth * pxByteSize, area.GetHeight(), + srcMode, 0, opa, screenBuffer, screenBufferWidth * bufferPxSize, bufferMode, maskedArea.GetLeft(), + maskedArea.GetTop())) { + return; + } +#endif + screenBuffer += static_cast(screenBufferWidth) * maskedArea.GetTop() * bufferPxSize; + screenBuffer += static_cast(maskedArea.GetLeft()) * bufferPxSize; + + image += (static_cast(mapWidth) * imageY + imageX) * pxByteSize; + /* RGB565 RGB888 color mode, image src don't have alpha */ + BlendWithSoftWare(image, mapWidth * pxByteSize, srcMode, screenBuffer, screenBufferWidth * bufferPxSize, bufferMode, + maskedArea.GetWidth(), maskedArea.GetHeight(), opa); +} + +#if ENABLE_GFX_ENGINES +bool DrawUtils::FillAreaWithHardware(const Rect& fillArea, const ColorType& color, const OpacityType& opa) const +{ + if ((opa != OPA_OPAQUE) && (fillArea.GetSize() >= HARDWARE_ACC_SIZE_LIMIT)) { + AllocationInfo gfxAlloc = ScreenDeviceProxy::GetInstance()->GetAllocationInfo(); + LiteSurfaceData data; + data.phyAddr = gfxAlloc.phyAddr; + data.width = gfxAlloc.width; + data.height = gfxAlloc.height; + data.stride = gfxAlloc.stride; + data.pixelFormat = gfxAlloc.pixelFormat; + if (GfxEngines::GetInstance()->GfxFillArea(data, fillArea, color, opa)) { + return true; + } + } + return false; +} +#endif + +void DrawUtils::FillAreaWithSoftWare(const Rect& fillArea, + uint8_t* dest, + ColorMode mode, + uint8_t destByteSize, + int16_t destWidth, + const ColorType& color, + const OpacityType& opa) const +{ + int32_t halBufferDeltaByteLen = static_cast(destWidth) * destByteSize; + int16_t width = fillArea.GetWidth(); + int16_t height = fillArea.GetHeight(); + int32_t offset = static_cast(fillArea.GetTop()) * destWidth + fillArea.GetLeft(); + dest += offset * destByteSize; + int32_t dstMaxSize = (ScreenDeviceProxy::GetInstance()->GetScreenArea() - offset) * destByteSize; + Color32 fillColor; + fillColor.full = Color::ColorTo32(color); + uint8_t* dstTmp = nullptr; + + if ((fillColor.alpha == OPA_TRANSPARENT) || (opa == OPA_TRANSPARENT)) { + return; + } + /* cover mode */ + if ((opa == OPA_OPAQUE) && (fillColor.alpha == OPA_OPAQUE)) { + for (int16_t col = 0; col < width; ++col) { + dstTmp = dest + (col * destByteSize); + COLOR_FILL_COVER(dstTmp, mode, fillColor.red, fillColor.green, fillColor.blue, ARGB8888); + } + uint8_t* memStart = dest; + int32_t memSize = static_cast(width) * destByteSize; + dest += destWidth * destByteSize; + dstMaxSize -= halBufferDeltaByteLen; + for (int16_t row = 1; row < height; ++row) { +#ifdef ARM_NEON_OPT + { + DEBUG_PERFORMANCE_TRACE("memcpy_neon"); + NeonMemcpy(dest, dstMaxSize, memStart, memSize); + } +#else + { + DEBUG_PERFORMANCE_TRACE("memcpy"); + if (memcpy_s(dest, dstMaxSize, memStart, memSize) != EOK) { + GRAPHIC_LOGE("DrawUtils::FillAreaWithSoftWare memcpy failed!\n"); + return; + } + } +#endif + dest += destWidth * destByteSize; + dstMaxSize -= halBufferDeltaByteLen; + } + } else { +#ifdef ARM_NEON_OPT + { + DEBUG_PERFORMANCE_TRACE("FillAreaWithSoftWare_neon"); + NeonBlendPipeLine pipeLine; + pipeLine.Construct(mode, ARGB8888, &fillColor, opa); + int16_t step = NEON_STEP_8 * GetByteSizeByColorMode(mode); + for (int16_t row = 0; row < height; ++row) { + uint8_t* buf = dest; + int16_t tmpWidth = width; + while (tmpWidth >= NEON_STEP_8) { + pipeLine.Invoke(buf); + buf += step; + tmpWidth -= NEON_STEP_8; + } + for (int16_t i = 0; i < tmpWidth; ++i) { + COLOR_FILL_BLEND(buf, mode, &fillColor, ARGB8888, opa); + buf += destByteSize; + } + dest += halBufferDeltaByteLen; + } + } +#else + { + DEBUG_PERFORMANCE_TRACE("FillAreaWithSoftWare"); + for (int16_t row = 0; row < height; row++) { + for (int16_t col = 0; col < width; col++) { + dstTmp = dest + (col * destByteSize); + COLOR_FILL_BLEND(dstTmp, mode, &fillColor, ARGB8888, opa); + } + dest += destWidth * destByteSize; + } + } +#endif + } +} + +void DrawUtils::BlendWithSoftWare(const uint8_t* src, + uint32_t srcStride, + ColorMode srcMode, + uint8_t* dest, + uint32_t destStride, + ColorMode destMode, + uint32_t width, + uint32_t height, + OpacityType opa) const +{ + uint8_t destByteSize = GetByteSizeByColorMode(destMode); + uint8_t srcByteSize = GetByteSizeByColorMode(srcMode); +#ifdef ARM_NEON_OPT + { + DEBUG_PERFORMANCE_TRACE("BlendWithSoftWare_neon"); + NeonBlendPipeLine pipeLine; + pipeLine.Construct(destMode, srcMode); + int16_t dstStep = NEON_STEP_8 * GetByteSizeByColorMode(destMode); + int16_t srcStep = NEON_STEP_8 * GetByteSizeByColorMode(srcMode); + for (uint32_t row = 0; row < height; ++row) { + uint8_t* dstBuf = dest; + uint8_t* srcBuf = const_cast(src); + int16_t tmpWidth = width; + while (tmpWidth >= NEON_STEP_8) { + pipeLine.Invoke(dstBuf, srcBuf, opa); + dstBuf += dstStep; + srcBuf += srcStep; + tmpWidth -= NEON_STEP_8; + } + for (int16_t i = 0; i < tmpWidth; ++i) { + COLOR_FILL_BLEND(dstBuf, destMode, srcBuf, srcMode, opa); + dstBuf += destByteSize; + srcBuf += srcByteSize; + } + dest += destStride; + src += srcStride; + } + } +#else + { + DEBUG_PERFORMANCE_TRACE("BlendWithSoftWare"); + for (uint32_t row = 0; row < height; ++row) { + uint8_t* destTmp = dest; + uint8_t* srcTmp = const_cast(src); + for (uint32_t col = 0; col < width; ++col) { + COLOR_FILL_BLEND(destTmp, destMode, srcTmp, srcMode, opa); + destTmp += destByteSize; + srcTmp += srcByteSize; + } + dest += destStride; + src += srcStride; + } + } +#endif +} + +void DrawUtils::GetXAxisErrForJunctionLine(bool ignoreJunctionPoint, + bool isRightPart, + int32_t& xMinErr, + int32_t& xMaxErr) +{ + xMinErr = 0; + xMaxErr = 0; + if (ignoreJunctionPoint) { + if (isRightPart) { + xMinErr = 1; + } else { + xMaxErr = -1; + } + } +} + +void DrawUtils::GetTransformInitState(const TransformMap& transMap, + const Point& position, + const Rect& trans, + TransformInitState& init) +{ + int16_t x = trans.GetLeft(); + int16_t y = trans.GetTop(); + + init.duHorizon = transMap.invMatrix_.GetData()[0]; + init.dvHorizon = transMap.invMatrix_.GetData()[1]; + init.duVertical = transMap.invMatrix_.GetData()[3]; // 3:RSxy + init.dvVertical = transMap.invMatrix_.GetData()[4]; // 4:RSyy + + init.verticalU = (x - position.x) * init.duHorizon + (y - position.y) * init.duVertical + + transMap.invMatrix_.GetData()[6]; // 6:TRSx + init.verticalV = (x - position.x) * init.dvHorizon + (y - position.y) * init.dvVertical + + transMap.invMatrix_.GetData()[7]; // 7:TRSy +} + +inline void DrawUtils::StepToNextLine(TriangleEdge& edge1, TriangleEdge& edge2) +{ + edge1.curY++; + edge2.curY++; + edge1.curX += edge1.du / edge1.dv; + edge2.curX += edge2.du / edge2.dv; +} + +void DrawUtils::DrawTriangleAlphaBilinear(const TriangleScanInfo& in) +{ + int32_t maskLeft = in.mask.GetLeft(); + int32_t maskRight = in.mask.GetRight(); + ColorMode bufferMode = ScreenDeviceProxy::GetInstance()->GetBufferMode(); + for (int16_t y = in.yMin; y <= in.yMax; y++) { + int16_t xMin = MATH_MAX(static_cast(in.edge1.curX), maskLeft); + int16_t xMax = MATH_MIN(static_cast(in.edge2.curX), maskRight); + int16_t diffX = (xMin - static_cast(in.edge1.curX)); + in.init.verticalU += in.init.duHorizon * diffX; + in.init.verticalV += in.init.dvHorizon * diffX; +#if ENABLE_WINDOW + uint8_t* screenBuffer = in.screenBuffer + (y * in.screenBufferWidth + xMin) * in.bufferPxSize; +#else + uint8_t* screenBuffer = + in.screenBuffer + + (((y - in.screenBufferRect.GetTop()) * in.screenBufferWidth + (xMin - in.screenBufferRect.GetLeft())) * + in.bufferPxSize); +#endif + float u = in.init.verticalU; + float v = in.init.verticalV; + for (int16_t x = xMin; x <= xMax; x++) { + const int16_t intU = static_cast(u); + const int16_t intV = static_cast(v); + if ((u >= 0) && (intU < in.info.header.width - 1) && (v >= 0) && (intV < in.info.header.height - 1)) { + const int16_t intUPlus1 = intU + 1; + const int16_t intVPlus1 = intV + 1; + OpacityType p1 = GetPxAlphaForAlphaImg(in.info, {intU, intV}); + OpacityType p2 = GetPxAlphaForAlphaImg(in.info, {intUPlus1, intV}); + OpacityType p3 = GetPxAlphaForAlphaImg(in.info, {intU, intVPlus1}); + OpacityType p4 = GetPxAlphaForAlphaImg(in.info, {intUPlus1, intVPlus1}); + + const float decU = u - intU; + const float decV = v - intV; + const float decUMinus1 = 1.0f - decU; + const float decVMinus1 = 1.0f - decV; + + const int32_t w1 = static_cast(decUMinus1 * decVMinus1 * 256.0f); // 256:shift 8 bit left + const int32_t w2 = static_cast(decU * decVMinus1 * 256.0f); // 256:shift 8 bit left + const int32_t w3 = static_cast(decUMinus1 * decV * 256.0f); // 256:shift 8 bit left + const int32_t w4 = static_cast(decU * decV * 256.0f); // 256:shift 8 bit left + +#ifndef _LITEOS + const int32_t outA = p1 * w1 + p2 * w2 + p3 * w3 + p4 * w4; +#else + const int32_t outA = __SMUAD(p1, w1) + __SMUAD(p2, w2) + __SMUAD(p3, w3) + __SMUAD(p4, w4); +#endif + Color32 result; + result.full = Color::ColorTo32(in.color); + result.alpha = static_cast(outA >> 8); // 8:shift 8 bit right + COLOR_FILL_BLEND(screenBuffer, bufferMode, &result, ARGB8888, in.opaScale); + } + u += in.init.duHorizon; + v += in.init.dvHorizon; + screenBuffer += in.bufferPxSize; + } + StepToNextLine(in.edge1, in.edge2); + in.init.verticalU += in.init.duVertical; + in.init.verticalV += in.init.dvVertical; + int16_t deltaX = static_cast(in.edge1.curX) - xMin; + in.init.verticalU += in.init.duHorizon * deltaX; + in.init.verticalV += in.init.dvHorizon * deltaX; + } +} + +void DrawUtils::DrawTriangleTrueColorBilinear565(const TriangleScanInfo& in) +{ + ColorMode bufferMode = ScreenDeviceProxy::GetInstance()->GetBufferMode(); + for (int16_t y = in.yMin; y <= in.yMax; y++) { + int16_t xMin = static_cast(in.edge1.curX); + int16_t xMax = static_cast(in.edge2.curX); +#if ENABLE_WINDOW + uint8_t* screenBuffer = in.screenBuffer + (y * in.screenBufferWidth + xMin) * in.bufferPxSize; +#else + uint8_t* screenBuffer = + in.screenBuffer + + (((y - in.screenBufferRect.GetTop()) * in.screenBufferWidth + (xMin - in.screenBufferRect.GetLeft())) * + in.bufferPxSize); +#endif + float u = in.init.verticalU; + float v = in.init.verticalV; + for (int16_t x = xMin; x <= xMax; x++) { + const int16_t intU = static_cast(u); + const int16_t intV = static_cast(v); + if ((u >= 0) && (intU < in.info.header.width - 1) && (v >= 0) && (intV < in.info.header.height - 1)) { +#ifndef _LITEOS + uint32_t px1 = intV * in.srcLineWidth + intU * in.pixelSize; +#else + uint32_t val1 = __SMUAD(intV, in.srcLineWidth); + uint32_t val2 = __SMUAD(intU, in.pixelSize); + uint32_t px1 = val1 + val2; +#endif + uint8_t* imgHead = const_cast(in.info.data); + const Color16 p1 = *(reinterpret_cast(&imgHead[px1])); + const Color16 p2 = *(reinterpret_cast(&imgHead[px1 + in.pixelSize])); + const Color16 p3 = *(reinterpret_cast(&imgHead[px1 + in.srcLineWidth])); + const Color16 p4 = *(reinterpret_cast(&imgHead[px1 + in.srcLineWidth + in.pixelSize])); + + const float decU = u - intU; + const float decV = v - intV; + const float decUMinus1 = 1 - decU; + const float decVMinus1 = 1 - decV; + + const int32_t w1 = static_cast(decUMinus1 * decVMinus1 * 256.0f); // 256:shift 8 bit left + const int32_t w2 = static_cast(decU * decVMinus1 * 256.0f); // 256:shift 8 bit left + const int32_t w3 = static_cast(decUMinus1 * decV * 256.0f); // 256:shift 8 bit left + const int32_t w4 = static_cast(decU * decV * 256.0f); // 256:shift 8 bit left +#ifndef _LITEOS + const int32_t outR = p1.red * w1 + p2.red * w2 + p3.red * w3 + p4.red * w4; + const int32_t outG = p1.green * w1 + p2.green * w2 + p3.green * w3 + p4.green * w4; + const int32_t outB = p1.blue * w1 + p2.blue * w2 + p3.blue * w3 + p4.blue * w4; +#else + const int32_t outR = + __SMUAD(p1.red, w1) + __SMUAD(p2.red, w2) + __SMUAD(p3.red, w3) + __SMUAD(p4.red, w4); + const int32_t outG = + __SMUAD(p1.green, w1) + __SMUAD(p2.green, w2) + __SMUAD(p3.green, w3) + __SMUAD(p4.green, w4); + const int32_t outB = + __SMUAD(p1.blue, w1) + __SMUAD(p2.blue, w2) + __SMUAD(p3.blue, w3) + __SMUAD(p4.blue, w4); +#endif + + Color16 result; + result.red = static_cast(outR >> 5); // 5:shift 5 bit right + result.green = static_cast(outG >> 6); // 6:shift 6 bit right + result.blue = static_cast(outB >> 5); // 5:shift 5 bit right + if (in.opaScale == OPA_OPAQUE) { + COLOR_FILL_COVER(screenBuffer, bufferMode, result.red, result.green, result.blue, RGB565); + } else { + COLOR_FILL_BLEND(screenBuffer, bufferMode, &result, RGB565, in.opaScale); + } + } + u += in.init.duHorizon; + v += in.init.dvHorizon; + screenBuffer += in.bufferPxSize; + } + StepToNextLine(in.edge1, in.edge2); + in.init.verticalU += in.init.duVertical; + in.init.verticalV += in.init.dvVertical; + int16_t deltaX = static_cast(in.edge1.curX) - xMin; + in.init.verticalU += in.init.duHorizon * deltaX; + in.init.verticalV += in.init.dvHorizon * deltaX; + } +} + +void DrawUtils::DrawTriangleTrueColorBilinear888(const TriangleScanInfo& in) +{ + ColorMode bufferMode = ScreenDeviceProxy::GetInstance()->GetBufferMode(); + for (int16_t y = in.yMin; y <= in.yMax; y++) { + int16_t xMin = static_cast(in.edge1.curX); + int16_t xMax = static_cast(in.edge2.curX); +#if ENABLE_WINDOW + uint8_t* screenBuffer = in.screenBuffer + (y * in.screenBufferWidth + xMin) * in.bufferPxSize; +#else + uint8_t* screenBuffer = + in.screenBuffer + + (((y - in.screenBufferRect.GetTop()) * in.screenBufferWidth + (xMin - in.screenBufferRect.GetLeft())) * + in.bufferPxSize); +#endif + float u = in.init.verticalU; + float v = in.init.verticalV; + for (int16_t x = xMin; x <= xMax; x++) { + const int16_t intU = static_cast(u); + const int16_t intV = static_cast(v); + if ((u >= 0) && (intU < in.info.header.width - 1) && (v >= 0) && (intV < in.info.header.height - 1)) { +#ifndef _LITEOS + uint32_t px1 = intV * in.srcLineWidth + intU * in.pixelSize; +#else + uint32_t val1 = __SMUAD(intV, in.srcLineWidth); + uint32_t val2 = __SMUAD(intU, in.pixelSize); + uint32_t px1 = val1 + val2; +#endif + uint8_t* imgHead = const_cast(in.info.data); + const Color24 p1 = *(reinterpret_cast(&imgHead[px1])); + const Color24 p2 = *(reinterpret_cast(&imgHead[px1 + in.pixelSize])); + const Color24 p3 = *(reinterpret_cast(&imgHead[px1 + in.srcLineWidth])); + const Color24 p4 = *(reinterpret_cast(&imgHead[px1 + in.srcLineWidth + in.pixelSize])); + + const float decU = u - intU; + const float decV = v - intV; + const float decUMinus1 = 1 - decU; + const float decVMinus1 = 1 - decV; + + const int32_t w1 = static_cast(decUMinus1 * decVMinus1 * 256.0f); // 256:shift 8 bit left + const int32_t w2 = static_cast(decU * decVMinus1 * 256.0f); // 256:shift 8 bit left + const int32_t w3 = static_cast(decUMinus1 * decV * 256.0f); // 256:shift 8 bit left + const int32_t w4 = static_cast(decU * decV * 256.0f); // 256:shift 8 bit left +#ifndef _LITEOS + const int32_t outR = p1.red * w1 + p2.red * w2 + p3.red * w3 + p4.red * w4; + const int32_t outG = p1.green * w1 + p2.green * w2 + p3.green * w3 + p4.green * w4; + const int32_t outB = p1.blue * w1 + p2.blue * w2 + p3.blue * w3 + p4.blue * w4; +#else + const int32_t outR = + __SMUAD(p1.red, w1) + __SMUAD(p2.red, w2) + __SMUAD(p3.red, w3) + __SMUAD(p4.red, w4); + const int32_t outG = + __SMUAD(p1.green, w1) + __SMUAD(p2.green, w2) + __SMUAD(p3.green, w3) + __SMUAD(p4.green, w4); + const int32_t outB = + __SMUAD(p1.blue, w1) + __SMUAD(p2.blue, w2) + __SMUAD(p3.blue, w3) + __SMUAD(p4.blue, w4); +#endif + + Color24 result; + result.red = static_cast(outR >> 8); // 8:shift 8 bit right + result.green = static_cast(outG >> 8); // 8:shift 8 bit right + result.blue = static_cast(outB >> 8); // 8:shift 8 bit right + if (in.opaScale == OPA_OPAQUE) { + COLOR_FILL_COVER(screenBuffer, bufferMode, result.red, result.green, result.blue, RGB888); + } else { + COLOR_FILL_BLEND(screenBuffer, bufferMode, &result, RGB888, in.opaScale); + } + } + u += in.init.duHorizon; + v += in.init.dvHorizon; + screenBuffer += in.bufferPxSize; + } + StepToNextLine(in.edge1, in.edge2); + in.init.verticalU += in.init.duVertical; + in.init.verticalV += in.init.dvVertical; + int16_t deltaX = static_cast(in.edge1.curX) - xMin; + in.init.verticalU += in.init.duHorizon * deltaX; + in.init.verticalV += in.init.dvHorizon * deltaX; + } +} + +static void DrawTriangleTrueColorBilinear8888Inner(const TriangleScanInfo& in, + uint8_t* screenBuffer, + int16_t len, + float u, + float v) +{ + ColorMode bufferMode = ScreenDeviceProxy::GetInstance()->GetBufferMode(); + for (int16_t x = 0; x < len; ++x) { + const int16_t intU = static_cast(u); + const int16_t intV = static_cast(v); + if ((u >= 0) && (intU < in.info.header.width - 1) && (v >= 0) && (intV < in.info.header.height - 1)) { +#ifndef _LITEOS + uint32_t px1 = intV * in.srcLineWidth + intU * in.pixelSize; +#else + uint32_t val1 = __SMUAD(intV, in.srcLineWidth); + uint32_t val2 = __SMUAD(intU, in.pixelSize); + uint32_t px1 = val1 + val2; +#endif + uint8_t* imgHead = const_cast(in.info.data); + const ColorType p1 = *(reinterpret_cast(&imgHead[px1])); + const ColorType p2 = *(reinterpret_cast(&imgHead[px1 + in.pixelSize])); + const ColorType p3 = *(reinterpret_cast(&imgHead[px1 + in.srcLineWidth])); + const ColorType p4 = *(reinterpret_cast(&imgHead[px1 + in.srcLineWidth + in.pixelSize])); + + const float decU = u - intU; + const float decV = v - intV; + const float decUMinus1 = 1 - decU; + const float decVMinus1 = 1 - decV; + + const int32_t w1 = static_cast(decUMinus1 * decVMinus1 * 256.0f); // 256:shift 8 bit left + const int32_t w2 = static_cast(decU * decVMinus1 * 256.0f); // 256:shift 8 bit left + const int32_t w3 = static_cast(decUMinus1 * decV * 256.0f); // 256:shift 8 bit left + const int32_t w4 = static_cast(decU * decV * 256.0f); // 256:shift 8 bit left +#ifndef _LITEOS + const int32_t outR = p1.red * w1 + p2.red * w2 + p3.red * w3 + p4.red * w4; + const int32_t outG = p1.green * w1 + p2.green * w2 + p3.green * w3 + p4.green * w4; + const int32_t outB = p1.blue * w1 + p2.blue * w2 + p3.blue * w3 + p4.blue * w4; + const int32_t outA = p1.alpha * w1 + p2.alpha * w2 + p3.alpha * w3 + p4.alpha * w4; +#else + const int32_t outR = __SMUAD(p1.red, w1) + __SMUAD(p2.red, w2) + __SMUAD(p3.red, w3) + __SMUAD(p4.red, w4); + const int32_t outG = + __SMUAD(p1.green, w1) + __SMUAD(p2.green, w2) + __SMUAD(p3.green, w3) + __SMUAD(p4.green, w4); + const int32_t outB = + __SMUAD(p1.blue, w1) + __SMUAD(p2.blue, w2) + __SMUAD(p3.blue, w3) + __SMUAD(p4.blue, w4); + const int32_t outA = + __SMUAD(p1.alpha, w1) + __SMUAD(p2.alpha, w2) + __SMUAD(p3.alpha, w3) + __SMUAD(p4.alpha, w4); +#endif + + Color32 result; + result.red = static_cast(outR >> 8); // 8:shift 8 bit right + result.green = static_cast(outG >> 8); // 8:shift 8 bit right + result.blue = static_cast(outB >> 8); // 8:shift 8 bit right + result.alpha = static_cast(outA >> 8); // 8:shift 8 bit right + if ((in.opaScale == OPA_OPAQUE) && (result.alpha == OPA_OPAQUE)) { + COLOR_FILL_COVER(screenBuffer, bufferMode, result.red, result.green, result.blue, ARGB8888); + } else { + COLOR_FILL_BLEND(screenBuffer, bufferMode, &result, ARGB8888, in.opaScale); + } + } + u += in.init.duHorizon; + v += in.init.dvHorizon; + screenBuffer += in.bufferPxSize; + } +} + +#ifdef ARM_NEON_OPT +static void DrawTriangleTrueColorBilinear8888InnerNeon(const TriangleScanInfo& in, + uint8_t* screenBuffer, + int16_t len, + float u, + float v, + NeonBlendPipeLine& pipeLine) +{ + ColorType arrayp1[NEON_STEP_8] = {0}; + ColorType arrayp2[NEON_STEP_8] = {0}; + ColorType arrayp3[NEON_STEP_8] = {0}; + ColorType arrayp4[NEON_STEP_8] = {0}; + float arrayU[NEON_STEP_8] = {0}; + float arrayV[NEON_STEP_8] = {0}; + int32_t arrayPx1[NEON_STEP_8] = {0}; + int16_t step = in.bufferPxSize * NEON_STEP_8; + while (len >= NEON_STEP_8) { + for (uint32_t i = 0; i < NEON_STEP_8; ++i) { + arrayU[i] = u; + arrayV[i] = v; + u += in.init.duHorizon; + v += in.init.dvHorizon; + } + // Monotonically increasing or decreasing, so only judge the beginning and end. + if ((arrayU[0] >= 0) && (arrayU[0] < in.info.header.width - 1) && + (arrayV[0] >= 0) && (arrayV[0] < in.info.header.height - 1) && + (arrayU[NEON_STEP_8 - 1] >= 0) && (arrayU[NEON_STEP_8 - 1] < in.info.header.width - 1) && + (arrayV[NEON_STEP_8 - 1] >= 0) && (arrayV[NEON_STEP_8 - 1] < in.info.header.height - 1)) { + // Process the lower half of arrayU and arrayV + float32x4_t vU = vld1q_f32(arrayU); + float32x4_t vV = vld1q_f32(arrayV); + int32x4_t vIntU = vcvtq_s32_f32(vU); + int32x4_t vIntV = vcvtq_s32_f32(vV); + int32x4_t vPx1 = + vaddq_s32(vmulq_s32(vIntV, vdupq_n_s32(in.srcLineWidth)), vmulq_s32(vIntU, vdupq_n_s32(in.pixelSize))); + vst1q_s32(arrayPx1, vPx1); + float32x4_t vDecU = vsubq_f32(vU, vcvtq_f32_s32(vIntU)); + float32x4_t vDecV = vsubq_f32(vV, vcvtq_f32_s32(vIntV)); + float32x4_t vDecUMinus1 = vsubq_f32(vdupq_n_f32(1.0), vDecU); + float32x4_t vDecVMinus1 = vsubq_f32(vdupq_n_f32(1.0), vDecV); + // 256:shift 8 bit left + uint32x4_t vLowW1 = vcvtq_u32_f32(vmulq_f32(vmulq_f32(vDecUMinus1, vDecVMinus1), vdupq_n_f32(256.0))); + uint32x4_t vLowW2 = vcvtq_u32_f32(vmulq_f32(vmulq_f32(vDecU, vDecVMinus1), vdupq_n_f32(256.0))); + uint32x4_t vLowW3 = vcvtq_u32_f32(vmulq_f32(vmulq_f32(vDecUMinus1, vDecV), vdupq_n_f32(256.0))); + uint32x4_t vLowW4 = vcvtq_u32_f32(vmulq_f32(vmulq_f32(vDecU, vDecV), vdupq_n_f32(256.0))); + // Process the higher half of arrayU and arrayV + vU = vld1q_f32(arrayU + NEON_STEP_4); + vV = vld1q_f32(arrayV + NEON_STEP_4); + vIntU = vcvtq_s32_f32(vU); + vIntV = vcvtq_s32_f32(vV); + vPx1 = + vaddq_s32(vmulq_s32(vIntV, vdupq_n_s32(in.srcLineWidth)), vmulq_s32(vIntU, vdupq_n_s32(in.pixelSize))); + vst1q_s32(arrayPx1 + NEON_STEP_4, vPx1); + vDecU = vsubq_f32(vU, vcvtq_f32_s32(vIntU)); + vDecV = vsubq_f32(vV, vcvtq_f32_s32(vIntV)); + vDecUMinus1 = vsubq_f32(vdupq_n_f32(1.0), vDecU); + vDecVMinus1 = vsubq_f32(vdupq_n_f32(1.0), vDecV); + // 256:shift 8 bit left + uint32x4_t vHighW1 = vcvtq_u32_f32(vmulq_f32(vmulq_f32(vDecUMinus1, vDecVMinus1), vdupq_n_f32(256.0))); + uint32x4_t vHighW2 = vcvtq_u32_f32(vmulq_f32(vmulq_f32(vDecU, vDecVMinus1), vdupq_n_f32(256.0))); + uint32x4_t vHighW3 = vcvtq_u32_f32(vmulq_f32(vmulq_f32(vDecUMinus1, vDecV), vdupq_n_f32(256.0))); + uint32x4_t vHighW4 = vcvtq_u32_f32(vmulq_f32(vmulq_f32(vDecU, vDecV), vdupq_n_f32(256.0))); + + // joins two uint32x4_t vectors into a uint16x8_t vector + uint16x8_t vW1 = vcombine_u16(vmovn_u32(vLowW1), vmovn_u32(vHighW1)); + uint16x8_t vW2 = vcombine_u16(vmovn_u32(vLowW2), vmovn_u32(vHighW2)); + uint16x8_t vW3 = vcombine_u16(vmovn_u32(vLowW3), vmovn_u32(vHighW3)); + uint16x8_t vW4 = vcombine_u16(vmovn_u32(vLowW4), vmovn_u32(vHighW4)); + + uint8_t* imgHead = const_cast(in.info.data); + for (uint32_t i = 0; i < NEON_STEP_8; ++i) { + int32_t px1 = arrayPx1[i]; + arrayp1[i] = *(reinterpret_cast(&imgHead[px1])); + arrayp2[i] = *(reinterpret_cast(&imgHead[px1 + in.pixelSize])); + arrayp3[i] = *(reinterpret_cast(&imgHead[px1 + in.srcLineWidth])); + arrayp4[i] = *(reinterpret_cast(&imgHead[px1 + in.srcLineWidth + in.pixelSize])); + } + + uint8x8x4_t v4p1 = vld4_u8(reinterpret_cast(arrayp1)); + uint8x8x4_t v4p2 = vld4_u8(reinterpret_cast(arrayp2)); + uint8x8x4_t v4p3 = vld4_u8(reinterpret_cast(arrayp3)); + uint8x8x4_t v4p4 = vld4_u8(reinterpret_cast(arrayp4)); + uint8x8_t vOutB = + vshrn_n_u16(vmulq_u16(vmovl_u8(v4p1.val[NEON_B]), vW1) + vmulq_u16(vmovl_u8(v4p2.val[NEON_B]), vW2) + + vmulq_u16(vmovl_u8(v4p3.val[NEON_B]), vW3) + vmulq_u16(vmovl_u8(v4p4.val[NEON_B]), vW4), + 8); // 8:shift 8 bit right + uint8x8_t vOutG = + vshrn_n_u16(vmulq_u16(vmovl_u8(v4p1.val[NEON_G]), vW1) + vmulq_u16(vmovl_u8(v4p2.val[NEON_G]), vW2) + + vmulq_u16(vmovl_u8(v4p3.val[NEON_G]), vW3) + vmulq_u16(vmovl_u8(v4p4.val[NEON_G]), vW4), + 8); // 8:shift 8 bit right + uint8x8_t vOutR = + vshrn_n_u16(vmulq_u16(vmovl_u8(v4p1.val[NEON_R]), vW1) + vmulq_u16(vmovl_u8(v4p2.val[NEON_R]), vW2) + + vmulq_u16(vmovl_u8(v4p3.val[NEON_R]), vW3) + vmulq_u16(vmovl_u8(v4p4.val[NEON_R]), vW4), + 8); // 8:shift 8 bit right + uint8x8_t vOutA = + vshrn_n_u16(vmulq_u16(vmovl_u8(v4p1.val[NEON_A]), vW1) + vmulq_u16(vmovl_u8(v4p2.val[NEON_A]), vW2) + + vmulq_u16(vmovl_u8(v4p3.val[NEON_A]), vW3) + vmulq_u16(vmovl_u8(v4p4.val[NEON_A]), vW4), + 8); // 8:shift 8 bit right + vOutA = NeonMulDiv255(vdup_n_u8(in.opaScale), vOutA); + pipeLine.Invoke(screenBuffer, vOutR, vOutG, vOutB, vOutA); + } else { + DrawTriangleTrueColorBilinear8888Inner(in, screenBuffer, NEON_STEP_8, arrayU[0], arrayV[0]); + } + screenBuffer += step; + len -= NEON_STEP_8; + } + if (len > 0) { + DrawTriangleTrueColorBilinear8888Inner(in, screenBuffer, len, u, v); + } +} +#endif + +void DrawUtils::DrawTriangleTrueColorBilinear8888(const TriangleScanInfo& in) +{ +#ifdef ARM_NEON_OPT + ColorMode bufferMode = ScreenDeviceProxy::GetInstance()->GetBufferMode(); +#endif + int16_t maskLeft = in.mask.GetLeft(); + int16_t maskRight = in.mask.GetRight(); + int32_t xMinErr = 0; + int32_t xMaxErr = 0; + GetXAxisErrForJunctionLine(in.ignoreJunctionPoint, in.isRightPart, xMinErr, xMaxErr); +#ifdef ARM_NEON_OPT + NeonBlendPipeLine pipeLine; + pipeLine.Construct(bufferMode, ARGB8888); +#endif + for (int16_t y = in.yMin; y <= in.yMax; ++y) { + int16_t xMin = MATH_MAX(static_cast(in.edge1.curX + xMinErr), maskLeft); + int16_t xMax = MATH_MIN(static_cast(in.edge2.curX + xMaxErr), maskRight); + int16_t diffX = (xMin - static_cast(in.edge1.curX)); + in.init.verticalU += in.init.duHorizon * diffX; + in.init.verticalV += in.init.dvHorizon * diffX; + +#if ENABLE_WINDOW + uint8_t* screenBuffer = in.screenBuffer + (y * in.screenBufferWidth + xMin) * in.bufferPxSize; +#else + uint8_t* screenBuffer = + in.screenBuffer + + (((y - in.screenBufferRect.GetTop()) * in.screenBufferWidth + (xMin - in.screenBufferRect.GetLeft())) * + in.bufferPxSize); +#endif + float u = in.init.verticalU; + float v = in.init.verticalV; +#ifdef ARM_NEON_OPT + { + DEBUG_PERFORMANCE_TRACE("DrawTriangleTrueColorBilinear8888_neon"); + DrawTriangleTrueColorBilinear8888InnerNeon(in, screenBuffer, xMax - xMin + 1, u, v, pipeLine); + } +#else + { + DEBUG_PERFORMANCE_TRACE("DrawTriangleTrueColorBilinear8888"); + DrawTriangleTrueColorBilinear8888Inner(in, screenBuffer, xMax - xMin + 1, u, v); + } +#endif + StepToNextLine(in.edge1, in.edge2); + in.init.verticalU += in.init.duVertical; + in.init.verticalV += in.init.dvVertical; + int16_t deltaX = static_cast(in.edge1.curX) - xMin; + in.init.verticalU += in.init.duHorizon * deltaX; + in.init.verticalV += in.init.dvHorizon * deltaX; + } +} + +void DrawUtils::DrawTriangleTrueColorNearest(const TriangleScanInfo& in) +{ + int16_t maskLeft = in.mask.GetLeft(); + int16_t maskRight = in.mask.GetRight(); + int32_t xMinErr = 0; + int32_t xMaxErr = 0; + ColorMode bufferMode = ScreenDeviceProxy::GetInstance()->GetBufferMode(); + GetXAxisErrForJunctionLine(in.ignoreJunctionPoint, in.isRightPart, xMinErr, xMaxErr); + for (int16_t y = in.yMin; y <= in.yMax; y++) { + int16_t xMin = MATH_MAX(static_cast(in.edge1.curX + xMinErr), maskLeft); + int16_t xMax = MATH_MIN(static_cast(in.edge2.curX + xMaxErr), maskRight); + int16_t diffX = (xMin - static_cast(in.edge1.curX)); + in.init.verticalU += in.init.duHorizon * diffX; + in.init.verticalV += in.init.dvHorizon * diffX; +#if ENABLE_WINDOW + uint8_t* screenBuffer = in.screenBuffer + (y * in.screenBufferWidth + xMin) * in.bufferPxSize; +#else + uint8_t* screenBuffer = + in.screenBuffer + + (((y - in.screenBufferRect.GetTop()) * in.screenBufferWidth + (xMin - in.screenBufferRect.GetLeft())) * + in.bufferPxSize); +#endif + float u = in.init.verticalU; + float v = in.init.verticalV; + for (int16_t x = xMin; x <= xMax; x++) { + const int16_t intU = static_cast(u); + const int16_t intV = static_cast(v); + if ((u >= 0) && (intU < in.info.header.width - 1) && (v >= 0) && (intV < in.info.header.height - 1)) { +#ifndef _LITEOS + uint32_t px1 = intV * in.srcLineWidth + intU * in.pixelSize; +#else + uint32_t val1 = __SMUAD(intV, in.srcLineWidth); + uint32_t val2 = __SMUAD(intU, in.pixelSize); + uint32_t px1 = val1 + val2; +#endif + uint8_t* imgHead = const_cast(in.info.data); + OpacityType opa = in.opaScale; + + switch (in.info.header.colorMode) { + case RGB888: { + Color24 p24 = *(reinterpret_cast(&imgHead[px1])); + if (opa == OPA_OPAQUE) { + COLOR_FILL_COVER(screenBuffer, bufferMode, p24.red, p24.green, p24.blue, RGB888); + } else { + COLOR_FILL_BLEND(screenBuffer, bufferMode, &p24, RGB888, opa); + } + break; + } + case RGB565: { + Color16 p16 = *(reinterpret_cast(&imgHead[px1])); + if (opa == OPA_OPAQUE) { + COLOR_FILL_COVER(screenBuffer, bufferMode, p16.red, p16.green, p16.blue, RGB565); + } else { + COLOR_FILL_BLEND(screenBuffer, bufferMode, &p16, RGB565, opa); + } + break; + } + case ARGB8888: { + Color32 p32 = *(reinterpret_cast(&imgHead[px1])); + if ((in.opaScale == OPA_OPAQUE) && (p32.alpha == OPA_OPAQUE)) { + COLOR_FILL_COVER(screenBuffer, bufferMode, p32.red, p32.green, p32.blue, ARGB8888); + } else { + COLOR_FILL_BLEND(screenBuffer, bufferMode, &p32, ARGB8888, in.opaScale); + } + break; + } + default: + return; + } + } + u += in.init.duHorizon; + v += in.init.dvHorizon; + screenBuffer += in.bufferPxSize; + } + StepToNextLine(in.edge1, in.edge2); + in.init.verticalU += in.init.duVertical; + in.init.verticalV += in.init.dvVertical; + int16_t deltaX = static_cast(in.edge1.curX) - xMin; + in.init.verticalU += in.init.duHorizon * deltaX; + in.init.verticalV += in.init.dvHorizon * deltaX; + } +} + +void DrawUtils::DrawTriangleTransformPart(const TrianglePartInfo& part) +{ + part.edge1.curX += part.edge1.du * (part.yMin - part.edge1.curY) / part.edge1.dv; + part.edge1.curY = part.yMin; + part.edge2.curX += part.edge2.du * (part.yMin - part.edge2.curY) / part.edge2.dv; + part.edge2.curY = part.yMin; + + Rect line; + line.SetLeft(static_cast(part.edge1.curX)); + line.SetRight(static_cast(part.edge1.curX)); + line.SetTop(static_cast(part.edge1.curY)); + line.SetBottom(static_cast(part.edge1.curY)); + TransformInitState init; + GetTransformInitState(part.transMap, part.position, line, init); + + uint16_t screenBufferWidth = ScreenDeviceProxy::GetInstance()->GetBufferWidth(); + uint8_t* screenBuffer = ScreenDeviceProxy::GetInstance()->GetBuffer(); + ColorMode bufferMode = ScreenDeviceProxy::GetInstance()->GetBufferMode(); + uint8_t bufferPxSize = GetByteSizeByColorMode(bufferMode); + if (screenBuffer == nullptr) { + return; + } + Rect bufferRect = ScreenDeviceProxy::GetInstance()->GetBufferRect(); + uint8_t pixelSize; + DrawTriangleTransformFuc fuc; + bool isTrueColor = (part.info.header.colorMode == ARGB8888) || (part.info.header.colorMode == RGB888) || + (part.info.header.colorMode == RGB565); + if (isTrueColor) { + pixelSize = part.info.pxSize >> SHIFT_3; + if (part.info.algorithm == TransformAlgorithm::NEAREST_NEIGHBOR) { + fuc = DrawTriangleTrueColorNearest; + } else if (part.info.header.colorMode == ARGB8888) { + fuc = DrawTriangleTrueColorBilinear8888; + } else if (part.info.header.colorMode == RGB888) { + fuc = DrawTriangleTrueColorBilinear888; + } else { + fuc = DrawTriangleTrueColorBilinear565; + } + } else { + pixelSize = part.info.pxSize; + fuc = DrawTriangleAlphaBilinear; + } + const int32_t srcLineWidth = part.info.header.width * pixelSize; + TriangleScanInfo input{part.yMin, + part.yMax, + part.edge1, + part.edge2, + screenBuffer, + bufferPxSize, + bufferRect, + part.color, + part.opaScale, + init, + screenBufferWidth, + pixelSize, + srcLineWidth, + part.info, + part.mask, + part.isRightPart, + part.ignoreJunctionPoint}; + fuc(input); +} + +void DrawUtils::DrawTriangleTransform(const Rect& mask, + const Point& position, + const ColorType& color, + OpacityType opaScale, + const TransformMap& transMap, + const TriangleTransformDataInfo& triangleInfo) +{ + bool p3IsInRight = ((triangleInfo.p1.y - triangleInfo.p2.y) * triangleInfo.p3.x + + (triangleInfo.p2.x - triangleInfo.p1.x) * triangleInfo.p3.y + + triangleInfo.p1.x * triangleInfo.p2.y - triangleInfo.p2.x * triangleInfo.p1.y) < 0; + TriangleEdge edge1; + TriangleEdge edge2; + TrianglePartInfo part{ + mask, + transMap, + position, + edge1, + edge2, + 0, + 0, + triangleInfo.info, + color, + opaScale, + triangleInfo.isRightPart, + triangleInfo.ignoreJunctionPoint, + }; + + uint8_t yErr = 1; + if (triangleInfo.p2.y == triangleInfo.p1.y) { + yErr = 0; + goto BottomHalf; + } + if (p3IsInRight) { + edge1 = TriangleEdge(triangleInfo.p1.x, triangleInfo.p1.y, triangleInfo.p2.x, triangleInfo.p2.y); + edge2 = TriangleEdge(triangleInfo.p1.x, triangleInfo.p1.y, triangleInfo.p3.x, triangleInfo.p3.y); + } else { + edge2 = TriangleEdge(triangleInfo.p1.x, triangleInfo.p1.y, triangleInfo.p2.x, triangleInfo.p2.y); + edge1 = TriangleEdge(triangleInfo.p1.x, triangleInfo.p1.y, triangleInfo.p3.x, triangleInfo.p3.y); + } + + part.yMin = MATH_MAX(mask.GetTop(), triangleInfo.p1.y); + part.yMax = MATH_MIN(mask.GetBottom(), triangleInfo.p2.y); + part.edge1 = edge1; + part.edge2 = edge2; + DrawTriangleTransformPart(part); +BottomHalf: + if (triangleInfo.p2.y == triangleInfo.p3.y) { + return; + } + + if (triangleInfo.p2.y == triangleInfo.p1.y) { + if (triangleInfo.p1.x < triangleInfo.p2.x) { + edge1 = TriangleEdge(triangleInfo.p1.x, triangleInfo.p1.y, triangleInfo.p3.x, triangleInfo.p3.y); + edge2 = TriangleEdge(triangleInfo.p2.x, triangleInfo.p2.y, triangleInfo.p3.x, triangleInfo.p3.y); + } else { + edge2 = TriangleEdge(triangleInfo.p1.x, triangleInfo.p1.y, triangleInfo.p3.x, triangleInfo.p3.y); + edge1 = TriangleEdge(triangleInfo.p2.x, triangleInfo.p2.y, triangleInfo.p3.x, triangleInfo.p3.y); + } + } else { + if (p3IsInRight) { + edge1 = TriangleEdge(triangleInfo.p2.x, triangleInfo.p2.y, triangleInfo.p3.x, triangleInfo.p3.y); + } else { + edge2 = TriangleEdge(triangleInfo.p2.x, triangleInfo.p2.y, triangleInfo.p3.x, triangleInfo.p3.y); + } + } + + part.yMin = MATH_MAX(mask.GetTop(), triangleInfo.p2.y + yErr); + part.yMax = MATH_MIN(mask.GetBottom(), triangleInfo.p3.y); + part.edge1 = edge1; + part.edge2 = edge2; + DrawTriangleTransformPart(part); +} + +void DrawUtils::DrawTransform(const Rect& mask, + const Point& position, + const ColorType& color, + OpacityType opaScale, + const TransformMap& transMap, + const TransformDataInfo& dataInfo) const +{ + if (opaScale == OPA_TRANSPARENT) { + return; + } + Rect trans = transMap.GetBoxRect(); + trans.SetX(trans.GetX() + position.x); + trans.SetY(trans.GetY() + position.y); + if (!trans.Intersect(trans, mask)) { + return; + } +#if ENABLE_HARDWARE_ACCELERATION + DRAW_UTILS_PREPROCESS(opaScale); + TransformOption option; + option.algorithm = dataInfo.algorithm; + if (ScreenDeviceProxy::GetInstance()->HardwareTransform(dataInfo.data, + static_cast(dataInfo.header.colorMode), transMap.GetTransMapRect(), transMap.GetTransformMatrix(), + opaScale, Color::ColorTo32(color), mask, screenBuffer, screenBufferWidth * bufferPxSize, bufferMode, option)) { + return; + } +#endif + + TriangleTransformDataInfo triangleInfo{ + dataInfo, + }; + Polygon polygon = transMap.GetPolygon(); + Point p1; + p1.x = polygon[0].x_ + position.x; // 0:first point + p1.y = polygon[0].y_ + position.y; // 0:first point + Point p2; + p2.x = polygon[1].x_ + position.x; // 1:second point + p2.y = polygon[1].y_ + position.y; // 1:second point + Point p3; + p3.x = polygon[2].x_ + position.x; // 2:third point + p3.y = polygon[2].y_ + position.y; // 2:third point + triangleInfo.isRightPart = ((p1.y - p3.y) * p2.x + (p3.x - p1.x) * p2.y + p1.x * p3.y - p3.x * p1.y) < 0; + triangleInfo.isRightPart = (p1.y < p3.y) ? triangleInfo.isRightPart : !triangleInfo.isRightPart; + DrawTriangle::SortVertexs(p1, p2, p3); + triangleInfo.ignoreJunctionPoint = false; + triangleInfo.p1 = p1; + triangleInfo.p2 = p2; + triangleInfo.p3 = p3; + if ((triangleInfo.p1.y <= mask.GetBottom()) && (triangleInfo.p3.y >= mask.GetTop())) { + DrawTriangleTransform(mask, position, color, opaScale, transMap, triangleInfo); + } + + triangleInfo.ignoreJunctionPoint = true; + triangleInfo.isRightPart = !triangleInfo.isRightPart; + p1.x = polygon[0].x_ + position.x; // 0:first point + p1.y = polygon[0].y_ + position.y; // 0:first point + p3.x = polygon[2].x_ + position.x; // 2:third point + p3.y = polygon[2].y_ + position.y; // 2:third point + Point p4; + p4.x = polygon[3].x_ + position.x; // 3:fourth point + p4.y = polygon[3].y_ + position.y; // 3:fourth point + DrawTriangle::SortVertexs(p1, p3, p4); + triangleInfo.p1 = p1; + triangleInfo.p2 = p3; + triangleInfo.p3 = p4; + if ((triangleInfo.p1.y <= mask.GetBottom()) && (triangleInfo.p3.y >= mask.GetTop())) { + DrawTriangleTransform(mask, position, color, opaScale, transMap, triangleInfo); + } +} + +OpacityType DrawUtils::GetPxAlphaForAlphaImg(const TransformDataInfo& dataInfo, const Point& point) +{ + Point tmpPoint = point; + const uint8_t* bufU8 = const_cast(dataInfo.data); +#if ENABLE_SPEC_FONT + if (dataInfo.header.colorMode == A1) { + uint8_t bit = tmpPoint.x & 0x7; // 0x7: 1 byte is 8 bit, + tmpPoint.x = tmpPoint.x >> SHIFT_3; + + uint32_t px = (dataInfo.header.width >> SHIFT_3) * tmpPoint.y + tmpPoint.x; + // 1: A1 means 1 bit, 7: maximum offset in bytes + uint8_t pxOpa = (bufU8[px] & (1 << (7 - bit))) >> (7 - bit); + return pxOpa ? OPA_TRANSPARENT : OPA_OPAQUE; + } else if (dataInfo.header.colorMode == A2) { + uint8_t bit = (tmpPoint.x & 0x3) * 2; // 0x3: 0b0011, 2: A2 color mode + tmpPoint.x = tmpPoint.x >> SHIFT_2; + + uint32_t px = (dataInfo.header.width >> SHIFT_2) * tmpPoint.y + tmpPoint.x; + // 3: the value of 0b0011 + uint8_t pxOpa = (bufU8[px] & (3 << (SHIFT_6 - bit))) >> (SHIFT_6 - bit); + return pxOpa * OPACITY_STEP_A2; + } else if (dataInfo.header.colorMode == A8) { + uint32_t px = dataInfo.header.width * tmpPoint.y + tmpPoint.x; + return bufU8[px]; + } +#else + uint8_t letterWidthInByte = (dataInfo.header.width * dataInfo.pxSize) >> SHIFT_3; + // 0x7: for rounding + if ((dataInfo.header.width * dataInfo.pxSize) & 0x7) { + letterWidthInByte++; + } + uint8_t bit = (tmpPoint.x & 0x1) << SHIFT_2; + bufU8 += (tmpPoint.y * letterWidthInByte) + ((tmpPoint.x * dataInfo.pxSize) >> SHIFT_3); + // 0xF: 0b1111, get the data of the A4 color mode + uint8_t pxOpa = (*bufU8 & (0xF << bit)) >> (bit); + return pxOpa * OPACITY_STEP_A4; +#endif // ENABLE_SPEC_FONT +} + +void DrawUtils::DrawTranspantArea(const Rect& rect, const Rect& mask) +{ + FillArea(rect, mask, true, nullptr); +} + +void DrawUtils::DrawWithBuffer(const Rect& rect, const Rect& mask, const ColorType* colorBuf) +{ + FillArea(rect, mask, false, colorBuf); +} + +void DrawUtils::FillArea(const Rect& rect, const Rect& mask, bool isTransparent, const ColorType* colorBuf) +{ + Rect maskedArea; + if (!maskedArea.Intersect(rect, mask)) { + return; + } + + int16_t left = maskedArea.GetLeft(); + int16_t right = maskedArea.GetRight(); + int16_t top = maskedArea.GetTop(); + int16_t bottom = maskedArea.GetBottom(); + +#if !ENABLE_WINDOW + Rect bufferRect = ScreenDeviceProxy::GetInstance()->GetBufferRect(); + maskedArea.SetLeft(left - bufferRect.GetLeft()); + maskedArea.SetRight(right - bufferRect.GetLeft()); + maskedArea.SetTop(top - bufferRect.GetTop()); + maskedArea.SetBottom(bottom - bufferRect.GetTop()); +#endif + + uint16_t screenBufferWidth = ScreenDeviceProxy::GetInstance()->GetBufferWidth(); + uint8_t* mem = ScreenDeviceProxy::GetInstance()->GetBuffer(); + ColorMode bufferMode = ScreenDeviceProxy::GetInstance()->GetBufferMode(); + uint8_t bufferPxSize = GetByteSizeByColorMode(bufferMode); + + mem += top * screenBufferWidth * bufferPxSize; + if (isTransparent) { + uint16_t sz = (right - left + 1) * bufferPxSize; + for (int16_t row = top; row <= bottom; row++) { + if (memset_s(mem + (left * bufferPxSize), sz, 0, sz) != EOK) { + return; + } + mem += screenBufferWidth * bufferPxSize; + } + } else { + if (colorBuf == nullptr) { + return; + } + for (int16_t row = top; row <= bottom; row++) { + for (int16_t col = left; col <= right; col++) { +#if COLOR_DEPTH == 32 + COLOR_FILL_COVER(mem[col * bufferPxSize], bufferMode, colorBuf[row * screenBufferWidth + col].red, + colorBuf[row * screenBufferWidth + col].green, + colorBuf[row * screenBufferWidth + col].blue, ARGB8888); +#else + COLOR_FILL_COVER(mem[col * bufferPxSize], bufferMode, colorBuf[row * screenBufferWidth + col].red, + colorBuf[row * screenBufferWidth + col].green, + colorBuf[row * screenBufferWidth + col].blue, RGB565); +#endif + } + mem += screenBufferWidth * bufferPxSize; + } + } +} + +void DrawUtils::DrawAdjPixelInLine(int16_t x1, + int16_t y1, + int16_t x2, + int16_t y2, + const Rect& mask, + const ColorType& color, + OpacityType opa, + uint16_t weight) const +{ + DRAW_UTILS_PREPROCESS(opa); + Color32 result; + result.full = Color::ColorTo32(color); + if ((x1 >= mask.GetLeft()) && (x1 <= mask.GetRight()) && (y1 >= mask.GetTop()) && (y1 <= mask.GetBottom())) { + x1 -= bufferRect.GetLeft(); + y1 -= bufferRect.GetTop(); + screenBuffer += (y1 * screenBufferWidth + x1) * bufferPxSize; + OpacityType fillOpa = (weight ^ OPA_OPAQUE) * opa / OPA_OPAQUE; + COLOR_FILL_BLEND(screenBuffer, bufferMode, &result, ARGB8888, fillOpa); + } + if ((x2 >= mask.GetLeft()) && (x2 <= mask.GetRight()) && (y2 >= mask.GetTop()) && (y2 <= mask.GetBottom())) { + x2 -= bufferRect.GetLeft(); + y2 -= bufferRect.GetTop(); + screenBuffer = ScreenDeviceProxy::GetInstance()->GetBuffer(); + screenBuffer += (y2 * screenBufferWidth + x2) * bufferPxSize; + OpacityType fillOpa = weight * opa / OPA_OPAQUE; + COLOR_FILL_BLEND(screenBuffer, bufferMode, &result, ARGB8888, fillOpa); + } +} + +void DrawUtils::DrawPixelInLine(int16_t x, + int16_t y, + const Rect& mask, + const ColorType& color, + OpacityType opa, + uint16_t weight) const +{ + DRAW_UTILS_PREPROCESS(opa); + Color32 result; + result.full = Color::ColorTo32(color); + if ((x >= mask.GetLeft()) && (x <= mask.GetRight()) && (y >= mask.GetTop()) && (y <= mask.GetBottom())) { + x -= bufferRect.GetLeft(); + y -= bufferRect.GetTop(); + screenBuffer += (y * screenBufferWidth + x) * bufferPxSize; + OpacityType fillOpa = weight * opa / OPA_OPAQUE; + COLOR_FILL_BLEND(screenBuffer, bufferMode, &result, ARGB8888, fillOpa); + } +} + +void DrawUtils::DrawVerPixelInLine(int16_t x, + int16_t y, + int8_t dir, + const Rect& mask, + const ColorType& color, + OpacityType opa, + uint16_t weight) const +{ + DRAW_UTILS_PREPROCESS(opa); + if ((y < mask.GetTop()) || (y > mask.GetBottom())) { + return; + } + Color32 result; + result.full = Color::ColorTo32(color); + int16_t x0 = x + dir; + int16_t x1 = x - dir; + y -= bufferRect.GetTop(); + if ((x0 >= mask.GetLeft()) && (x0 <= mask.GetRight())) { + x0 -= bufferRect.GetLeft(); + screenBuffer += (y * screenBufferWidth + x0) * bufferPxSize; + OpacityType fillOpa = weight * opa / OPA_OPAQUE; + COLOR_FILL_BLEND(screenBuffer, bufferMode, &result, ARGB8888, fillOpa); + } + if ((x >= mask.GetLeft()) && (x <= mask.GetRight())) { + x -= bufferRect.GetLeft(); + screenBuffer = ScreenDeviceProxy::GetInstance()->GetBuffer(); + screenBuffer += (y * screenBufferWidth + x) * bufferPxSize; + if (opa == OPA_OPAQUE) { + COLOR_FILL_COVER(screenBuffer, bufferMode, result.red, result.green, result.blue, ARGB8888); + } else { + COLOR_FILL_BLEND(screenBuffer, bufferMode, &result, ARGB8888, opa); + } + } + if ((x1 >= mask.GetLeft()) && (x1 <= mask.GetRight())) { + x1 -= bufferRect.GetLeft(); + screenBuffer = ScreenDeviceProxy::GetInstance()->GetBuffer(); + screenBuffer += (y * screenBufferWidth + x1) * bufferPxSize; + OpacityType fillOpa = (weight ^ OPA_OPAQUE) * opa / OPA_OPAQUE; + COLOR_FILL_BLEND(screenBuffer, bufferMode, &result, ARGB8888, fillOpa); + } +} + +void DrawUtils::DrawHorPixelInLine(int16_t x, + int16_t y, + int8_t dir, + const Rect& mask, + const ColorType& color, + OpacityType opa, + uint16_t weight) const +{ + DRAW_UTILS_PREPROCESS(opa); + if ((x < mask.GetLeft()) || (x > mask.GetRight())) { + return; + } + Color32 result; + result.full = Color::ColorTo32(color); + int16_t y0 = y + dir; + int16_t y1 = y - dir; + x -= bufferRect.GetLeft(); + if ((y0 >= mask.GetTop()) && (y0 <= mask.GetBottom())) { + y0 -= bufferRect.GetTop(); + screenBuffer += (y0 * screenBufferWidth + x) * bufferPxSize; + OpacityType fillOpa = weight * opa / OPA_OPAQUE; + COLOR_FILL_BLEND(screenBuffer, bufferMode, &result, ARGB8888, fillOpa); + } + if ((y >= mask.GetTop()) && (y <= mask.GetBottom())) { + y -= bufferRect.GetTop(); + screenBuffer = ScreenDeviceProxy::GetInstance()->GetBuffer(); + screenBuffer += (y * screenBufferWidth + x) * bufferPxSize; + if (opa == OPA_OPAQUE) { + COLOR_FILL_COVER(screenBuffer, bufferMode, result.red, result.green, result.blue, ARGB8888); + } else { + COLOR_FILL_BLEND(screenBuffer, bufferMode, &result, ARGB8888, opa); + } + } + if ((y1 >= mask.GetTop()) && (y1 <= mask.GetBottom())) { + y1 -= bufferRect.GetTop(); + screenBuffer = ScreenDeviceProxy::GetInstance()->GetBuffer(); + screenBuffer += (y1 * screenBufferWidth + x) * bufferPxSize; + OpacityType fillOpa = (weight ^ OPA_OPAQUE) * opa / OPA_OPAQUE; + COLOR_FILL_BLEND(screenBuffer, bufferMode, &result, ARGB8888, fillOpa); + } +} +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/draw/draw_utils.h b/frameworks/draw/draw_utils.h new file mode 100644 index 0000000..9c1fb1f --- /dev/null +++ b/frameworks/draw/draw_utils.h @@ -0,0 +1,291 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef GRAPHIC_LITE_DRAW_UTILS_H +#define GRAPHIC_LITE_DRAW_UTILS_H + +#include "color.h" +#include "dock/screen_device_proxy.h" +#include "common/text.h" +#include "geometry2d.h" +#include "graphic_types.h" +#include "style.h" +#include "transform.h" + +namespace OHOS { +#define SWAP_INT16(x, y) \ + do { \ + int16_t temp = (x); \ + (x) = (y); \ + (y) = temp; \ + } while (0) + +#define SWAP_POINTS(x1, x2, y1, y2) \ + SWAP_INT16(x1, x2); \ + SWAP_INT16(y1, y2); + +struct EdgeSides { + int16_t left; + int16_t right; + int16_t top; + int16_t bottom; +}; + +struct LabelLineInfo { + Point& pos; + Point& offset; + const Rect& mask; + int16_t lineHeight; + uint16_t lineLength; + uint8_t shapingId; + uint8_t opaScale; + const Style& style; + + const char* text; + uint16_t length; + uint16_t start; + uint8_t fontId; + uint8_t fontSize; + uint8_t txtFlag; + UITextLanguageDirect direct; + uint32_t* codePoints; +}; + +struct LabelLetterInfo { + const Point& pos; + Rect mask; + const ColorType& color; + OpacityType opa; + int8_t offsetX; + int8_t offsetY; + + const uint32_t& letter; + UITextLanguageDirect direct; + uint8_t fontId; + uint8_t shapingId; + uint8_t fontSize; +}; + +struct TransformInitState { + float verticalU; + float verticalV; + float duHorizon; + float dvHorizon; + float duVertical; + float dvVertical; +}; + +struct TriangleEdge { + TriangleEdge() {} + TriangleEdge(int16_t x1, int16_t y1, int16_t duInt, int16_t dvInt); + ~TriangleEdge(); + float curX = 0.0f; + float curY = 0.0f; + float du = 0.0f; + float dv = 0.0f; +}; +struct TransformDataInfo { + ImageHeader header; + const uint8_t* data; + uint8_t pxSize; + BlurLevel blurLevel; + TransformAlgorithm algorithm; +}; + +struct TriangleTransformDataInfo { + const TransformDataInfo& info; + Point p1; + Point p2; + Point p3; + bool isRightPart; + bool ignoreJunctionPoint; +}; + +struct TriangleScanInfo { + int16_t yMin; + int16_t yMax; + TriangleEdge& edge1; + TriangleEdge& edge2; + uint8_t* screenBuffer; + uint8_t bufferPxSize; + Rect screenBufferRect; + const ColorType& color; + const OpacityType opaScale; + TransformInitState& init; + uint16_t screenBufferWidth; + uint8_t pixelSize; + const int32_t srcLineWidth; + const TransformDataInfo& info; + const Rect& mask; + bool isRightPart; + bool ignoreJunctionPoint; +}; + +struct TrianglePartInfo { + const Rect& mask; + const TransformMap& transMap; + const Point& position; + TriangleEdge& edge1; + TriangleEdge& edge2; + int16_t yMin; + int16_t yMax; + const TransformDataInfo& info; + const ColorType& color; + const OpacityType opaScale; + bool isRightPart; + bool ignoreJunctionPoint; +}; + +enum { + IMG_SRC_VARIABLE, + IMG_SRC_FILE, + IMG_SRC_UNKNOWN, +}; + +enum PixelType { + IMG_RGB565 = 2, + IMG_RGB888 = 3, + IMG_ARGB8888 = 4, +}; + +class DrawUtils : public HeapBase { +public: + static DrawUtils* GetInstance() + { + static DrawUtils instance; + return &instance; + } + + void DrawColorArea(const Rect& area, const Rect& mask, const ColorType& color, OpacityType opa) const; + + void DrawColorAreaBySides(const Rect& mask, const ColorType& color, OpacityType opa, const EdgeSides& sides) const; + + void DrawPixel(int16_t x, int16_t y, const Rect& mask, const ColorType& color, OpacityType opa) const; + + void DrawLetter(const LabelLetterInfo& letterInfo) const; + + void DrawImage(const Rect& area, const Rect& mask, const uint8_t* image, OpacityType opa, uint8_t pxByteSize) const; + + static void + GetXAxisErrForJunctionLine(bool ignoreJunctionPoint, bool isRightPart, int32_t& xMinErr, int32_t& xMaxErr); + + static void GetTransformInitState(const TransformMap& transMap, + const Point& position, + const Rect& trans, + TransformInitState& init); + + static void DrawTriangleTransform(const Rect& mask, + const Point& position, + const ColorType& color, + OpacityType opaScale, + const TransformMap& transMap, + const TriangleTransformDataInfo& dataInfo); + + void DrawTransform(const Rect& mask, + const Point& position, + const ColorType& color, + OpacityType opaScale, + const TransformMap& transMap, + const TransformDataInfo& dataInfo) const; + + void DrawTranspantArea(const Rect& rect, const Rect& mask); + + void DrawWithBuffer(const Rect& rect, const Rect& mask, const ColorType* colorBuf); + + static uint8_t GetPxSizeByColorMode(uint8_t colorMode); + + static uint8_t GetByteSizeByColorMode(uint8_t colorMode); + + static uint8_t GetPxSizeByImageInfo(ImageInfo imageInfo); + + static OpacityType GetMixOpacity(OpacityType opa1, OpacityType opa2) + { + // 8: Shift right 8 bits + OpacityType opaMix = (opa1 == OPA_OPAQUE) ? opa2 : ((static_cast(opa1) * opa2) >> 8); + return opaMix; + } + + void DrawAdjPixelInLine(int16_t x1, + int16_t y1, + int16_t x2, + int16_t y2, + const Rect& mask, + const ColorType& color, + OpacityType opa, + uint16_t w) const; + + void DrawPixelInLine(int16_t x, int16_t y, const Rect& mask, const ColorType& color, OpacityType opa, uint16_t w) + const; + + void DrawVerPixelInLine(int16_t x, + int16_t y, + int8_t dir, + const Rect& mask, + const ColorType& color, + OpacityType opa, + uint16_t weight) const; + + void DrawHorPixelInLine(int16_t x, + int16_t y, + int8_t dir, + const Rect& mask, + const ColorType& color, + OpacityType opa, + uint16_t weight) const; + +private: +#if ENABLE_GFX_ENGINES + bool FillAreaWithHardware(const Rect& fillArea, const ColorType& color, const OpacityType& opa) const; +#endif + void FillAreaWithSoftWare(const Rect& fillArea, + uint8_t* mem, + ColorMode mode, + uint8_t destByteSize, + int16_t bufWidth, + const ColorType& color, + const OpacityType& opa) const; + + void BlendWithSoftWare(const uint8_t* src, + uint32_t srcStride, + ColorMode srcMode, + uint8_t* dest, + uint32_t destStride, + ColorMode destMode, + uint32_t width, + uint32_t height, + OpacityType opa) const; + + using DrawTriangleTransformFuc = void (*)(const TriangleScanInfo& triangle); + + static void DrawTriangleTrueColorNearest(const TriangleScanInfo& triangle); + + static void DrawTriangleAlphaBilinear(const TriangleScanInfo& triangle); + + static void DrawTriangleTrueColorBilinear565(const TriangleScanInfo& triangle); + + static void DrawTriangleTrueColorBilinear888(const TriangleScanInfo& triangle); + + static void DrawTriangleTrueColorBilinear8888(const TriangleScanInfo& triangle); + + inline static void StepToNextLine(TriangleEdge& edg1, TriangleEdge& edg2); + + static void DrawTriangleTransformPart(const TrianglePartInfo& part); + + static OpacityType GetPxAlphaForAlphaImg(const TransformDataInfo& dataInfo, const Point& point); + + void FillArea(const Rect& rect, const Rect& mask, bool isTransparent, const ColorType* colorBuf); +}; +} // namespace OHOS +#endif // GRAPHIC_LITE_DRAW_UTILS_H diff --git a/frameworks/events/event.cpp b/frameworks/events/event.cpp new file mode 100755 index 0000000..ed4b35e --- /dev/null +++ b/frameworks/events/event.cpp @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "events/event.h" +#include "hal_tick.h" + +namespace OHOS { +Event::Event() : timeStamp_(HALTick::GetInstance().GetTime()), curPos_({ 0, 0 }) {} + +Event::Event(const Point& curPos) : timeStamp_(HALTick::GetInstance().GetTime()), curPos_(curPos) {} +} // namespace OHOS diff --git a/frameworks/font/base_font.cpp b/frameworks/font/base_font.cpp new file mode 100755 index 0000000..4d99d3c --- /dev/null +++ b/frameworks/font/base_font.cpp @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "font/base_font.h" +namespace OHOS { +uint8_t BaseFont::GetBaseFontId() +{ + return fontId_; +} +void BaseFont::SetBaseFontId(uint8_t fontId) +{ + fontId_ = fontId; +} + +uintptr_t BaseFont::GetRamAddr() +{ + return ramAddr_; +} +void BaseFont::SetRamAddr(uintptr_t ramAddr) +{ + ramAddr_ = ramAddr; +} +uint32_t BaseFont::GetRamLen() +{ + return ramLen_; +} +void BaseFont::SetRamLen(uint32_t ramLen) +{ + ramLen_ = ramLen; +} + +void BaseFont::SetPsramMemory(uintptr_t psramAddr, uint32_t psramLen) +{ + SetRamAddr(psramAddr); + SetRamLen(psramLen); +} + +int8_t BaseFont::GetDefaultParamByLangId(uint8_t langId, LangTextParam** pParam) const +{ + if ((langId >= GetTotalLangId()) || (pParam == nullptr)) { + return INVALID_RET_VALUE; + } + + LangTextParam *pTable = GetLangTextDefaultParamTable(); + if (pTable == nullptr) { + return INVALID_RET_VALUE; + } + + *pParam = (pTable + langId); + return RET_VALUE_OK; +} +} // namespace OHOS diff --git a/frameworks/font/glyphs_manager.cpp b/frameworks/font/glyphs_manager.cpp new file mode 100755 index 0000000..61da98e --- /dev/null +++ b/frameworks/font/glyphs_manager.cpp @@ -0,0 +1,383 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "font/glyphs_manager.h" +#include "file.h" +#include "securec.h" + +namespace OHOS { +GlyphsManager::GlyphsManager() + : binHeader_{{0}}, + fontNum_(0), + start_(0), + fontHeaderSectionStart_(0), + fontIndexSectionStart_(0), + curFontIndexSectionStart_(0), + glyphNodeSectionStart_(0), + curGlyphNodeSectionStart_(0), + bitMapSectionStart_(0), + curBitMapSectionStart_(0), + ramAddr_(nullptr), + ramUsedLen_(0), + fontHeaderCache_(nullptr), + indexCache_(nullptr), + curIndexCache_(nullptr), + nodeCache_(nullptr), + cacheStatus_(nullptr), + fp_(-1), + curFontHeader_(nullptr), + curGlyphNode_(nullptr), + isRamSet_(false), + isFileSet_(false), + isFontIdSet_(false) +{ + fontId_ = GetBitmapFontIdMax(); +} +GlyphsManager::~GlyphsManager() {} + +int8_t GlyphsManager::GlyphNodeCacheInit() +{ + uint32_t size = 0; + for (int32_t i = 0; i < fontNum_; i++) { + size += fontHeaderCache_[i].indexLen; + } + + indexCache_ = ramAddr_ + ramUsedLen_; + ramUsedLen_ += size; + /* align up to 4 byte, power of 2 */ + ramUsedLen_ = AlignUp(ramUsedLen_, 2); + + int32_t ret = read(fp_, indexCache_, size); + if (ret != static_cast(size)) { + return INVALID_RET_VALUE; + } + + cacheStatus_ = reinterpret_cast(ramAddr_ + ramUsedLen_); + ramUsedLen_ += sizeof(CacheState); + /* align up to 4 byte, power of 2 */ + ramUsedLen_ = AlignUp(ramUsedLen_, 2); + for (int32_t font = 0; font < FONT_HASH_NR; font++) { + for (int32_t uc = 0; uc < UNICODE_HASH_NR; uc++) { + (*cacheStatus_)[font][uc] = 0; + } + } + + nodeCache_ = reinterpret_cast(ramAddr_ + ramUsedLen_); + ramUsedLen_ += sizeof(CacheType); + /* align up to 4 byte, power of 2 */ + ramUsedLen_ = AlignUp(ramUsedLen_, 2); + for (int32_t font = 0; font < FONT_HASH_NR; font++) { + for (int32_t uc = 0; uc < UNICODE_HASH_NR; uc++) { + for (int32_t node = 0; node < NODE_HASH_NR; node++) { + (*nodeCache_)[font][uc][node].unicode = 0; + } + } + } + + return RET_VALUE_OK; +} + +GlyphNode* GlyphsManager::GetNodeFromCache(uint32_t unicode) +{ + GlyphNode* node = nullptr; + + uint8_t font = fontId_ & FONT_HASH_MASK; + uint8_t uc = unicode & UNICODE_HASH_MASK; + for (uint8_t i = 0; i < NODE_HASH_NR; i++) { + GlyphNode* p = &((*nodeCache_)[font][uc][i]); + if ((p->unicode == unicode) && (p->reserve == fontId_)) { + node = p; + break; + } + } + return node; +} + +GlyphNode* GlyphsManager::GetNodeCacheSpace(uint32_t unicode) +{ + uint8_t font, uc, i; + GlyphNode* node = nullptr; + + font = fontId_ & FONT_HASH_MASK; + uc = unicode & UNICODE_HASH_MASK; + i = (*cacheStatus_)[font][uc]; + node = &((*nodeCache_)[font][uc][i]); + + i++; + if (i >= NODE_HASH_NR) { + i = 0; + } + (*cacheStatus_)[font][uc] = i; + + return node; +} + +GlyphNode* GlyphsManager::GetNodeFromFile(uint32_t unicode) +{ + uint16_t idx = 0; + uint8_t key; + uint32_t offset; + + for (int32_t i = RADIX_SHIFT_START; i >= 0; i -= RADIX_TREE_BITS) { + offset = idx * sizeof(IndexNode); + key = static_cast((unicode >> static_cast(i)) & RADIX_TREE_MASK); + offset += key * sizeof(uint16_t); + idx = *(reinterpret_cast(curIndexCache_ + offset)); + if (idx == 0) { + return nullptr; + } + } + + offset = curGlyphNodeSectionStart_ + (idx - 1) * sizeof(GlyphNode); + int32_t ret = lseek(fp_, offset, SEEK_SET); + if (ret != static_cast(offset)) { + return nullptr; + } + GlyphNode* node = GetNodeCacheSpace(unicode); + ret = read(fp_, node, sizeof(GlyphNode)); + if (ret < 0) { + return nullptr; + } + + return node; +} + +void GlyphsManager::SetRamBuffer(uintptr_t ramAddr) +{ + ramAddr_ = reinterpret_cast(ramAddr); + isRamSet_ = true; +} + +int8_t GlyphsManager::SetFile(int32_t fp, uint32_t start) +{ + if (!isRamSet_) { + return INVALID_RET_VALUE; + } + + fp_ = fp; + start_ = start; + int32_t ret = lseek(fp_, start_, SEEK_SET); + if (ret < 0) { + return INVALID_RET_VALUE; + } + ret = read(fp_, &binHeader_, sizeof(binHeader_)); + if (ret != sizeof(binHeader_)) { + return INVALID_RET_VALUE; + } + if (strncmp(binHeader_.fontMagic, FONT_MAGIC_NUMBER, FONT_MAGIC_NUM_LEN) != 0) { + return INVALID_RET_VALUE; + } + if (binHeader_.fontNum > GetBitmapFontIdMax()) { + return INVALID_RET_VALUE; + } + + fontNum_ = binHeader_.fontNum; + fontHeaderSectionStart_ = start_ + sizeof(binHeader_); + int32_t size = sizeof(FontHeader) * fontNum_; + fontIndexSectionStart_ = fontHeaderSectionStart_ + size; + + fontHeaderCache_ = reinterpret_cast(ramAddr_); + /* align up to 4 byte, power of 2 */ + ramUsedLen_ = AlignUp(size, 2); + + ret = read(fp_, fontHeaderCache_, size); + if (ret != size) { + return INVALID_RET_VALUE; + } + + FontHeader* last = fontHeaderCache_ + fontNum_ - 1; + size = last->indexOffset + last->indexLen; + glyphNodeSectionStart_ = fontIndexSectionStart_ + size; + + size = 0; + for (uint32_t i = 0; i < fontNum_; i++) { + size += fontHeaderCache_[i].glyphNum * sizeof(GlyphNode); + } + bitMapSectionStart_ = glyphNodeSectionStart_ + size; + ret = GlyphNodeCacheInit(); + if (ret == RET_VALUE_OK) { + isFileSet_ = true; + } + + fontId_ = GetBitmapFontIdMax(); + return ret; +} + +int8_t GlyphsManager::SetCurrentFontId(uint8_t fontId) +{ + uint16_t fontIdx = 0; + if (!isFileSet_) { + return INVALID_RET_VALUE; + } + if (fontId > GetBitmapFontIdMax()) { + return INVALID_RET_VALUE; + } + if (fontId_ == fontId) { + return RET_VALUE_OK; + } + + int32_t low = 0; + int32_t high = binHeader_.fontNum - 1; + bool found = false; + + while (low <= high) { + int32_t mid = (low + high) / 2; // 2 means half + if (fontHeaderCache_[mid].fontId == fontId) { + fontIdx = mid; + found = true; + break; + } else if (fontHeaderCache_[mid].fontId > fontId) { + high = mid - 1; + } else if (fontHeaderCache_[mid].fontId < fontId) { + low = mid + 1; + } + } + if (!found) { + isFontIdSet_ = false; + curFontHeader_ = nullptr; + fontId_ = GetBitmapFontIdMax(); + return INVALID_RET_VALUE; + } + + uint32_t size = 0; + fontId_ = fontId; + curFontHeader_ = fontHeaderCache_ + fontIdx; + curGlyphNode_ = nullptr; + curFontIndexSectionStart_ = fontIndexSectionStart_ + curFontHeader_->indexOffset; + for (uint32_t i = 0; i < fontIdx; i++) { + size += fontHeaderCache_[i].glyphNum * sizeof(GlyphNode); + } + curGlyphNodeSectionStart_ = glyphNodeSectionStart_ + size; + curBitMapSectionStart_ = bitMapSectionStart_ + curFontHeader_->glyphOffset; + curIndexCache_ = indexCache_ + curFontHeader_->indexOffset; + isFontIdSet_ = true; + + return RET_VALUE_OK; +} + +int32_t GlyphsManager::GetRamUsedLen() const +{ + if (!isFileSet_) { + return INVALID_RET_VALUE; + } + return ramUsedLen_; +} + +int8_t GlyphsManager::GetFontVersion(char* version, uint8_t len) const +{ + if (!isFileSet_ || (version == nullptr) || (len > FONT_VERSION_LEN)) { + return INVALID_RET_VALUE; + } + if (memset_s(version, len, 0, len) != EOK) { + return INVALID_RET_VALUE; + } + if (strcpy_s(version, len, binHeader_.fontVersion) != EOK) { + return INVALID_RET_VALUE; + } + return RET_VALUE_OK; +} + +const FontHeader* GlyphsManager::GetCurrentFontHeader() const +{ + if (!isFontIdSet_) { + return nullptr; + } + + if (curFontHeader_ == nullptr) { + return nullptr; + } + + return curFontHeader_; +} + +const GlyphNode* GlyphsManager::GetGlyphNode(uint32_t unicode) +{ + if (!isFontIdSet_) { + return nullptr; + } + + if (curGlyphNode_ != nullptr) { + if ((curGlyphNode_->unicode == unicode) && (curGlyphNode_->reserve == fontId_)) { + return curGlyphNode_; + } + } + GlyphNode* node = GetNodeFromCache(unicode); + if (node == nullptr) { + node = GetNodeFromFile(unicode); + if (node != nullptr) { + node->reserve = fontId_; + } + } + + curGlyphNode_ = node; + return node; +} + +int16_t GlyphsManager::GetFontHeight() const +{ + if (!isFontIdSet_) { + return INVALID_RET_VALUE; + } + + if (curFontHeader_ == nullptr) { + return INVALID_RET_VALUE; + } + + return curFontHeader_->fontHeight; +} + +int16_t GlyphsManager::GetFontWidth(uint32_t unicode) +{ + const GlyphNode* node = nullptr; + + if (!isFontIdSet_) { + return INVALID_RET_VALUE; + } + node = GetGlyphNode(unicode); + if (node == nullptr) { + return INVALID_RET_VALUE; + } + return node->advance; +} + +int8_t GlyphsManager::GetBitmap(uint32_t unicode, uint8_t* bitmap) +{ + if (bitmap == nullptr) { + return INVALID_RET_VALUE; + } + if (!isFontIdSet_) { + return INVALID_RET_VALUE; + } + + const GlyphNode* node = GetGlyphNode(unicode); + if (node == nullptr) { + return INVALID_RET_VALUE; + } + + uint32_t offset = curBitMapSectionStart_ + node->dataOff; + uint32_t size = node->kernOff - node->dataOff; + int32_t ret = lseek(fp_, offset, SEEK_SET); + if (ret != static_cast(offset)) { + return INVALID_RET_VALUE; + } + + int32_t readSize = read(fp_, bitmap, size); + if (readSize != static_cast(size)) { + return INVALID_RET_VALUE; + } + + return RET_VALUE_OK; +} +} // namespace OHOS diff --git a/frameworks/font/glyphs_manager.h b/frameworks/font/glyphs_manager.h new file mode 100755 index 0000000..d13d0eb --- /dev/null +++ b/frameworks/font/glyphs_manager.h @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef GLYPHS_MANAGER_FONT_H +#define GLYPHS_MANAGER_FONT_H + +#include "font/ui_font_header.h" + +namespace OHOS { +class GlyphsManager { +public: + GlyphsManager(); + + GlyphsManager(const GlyphsManager&) = delete; + + GlyphsManager& operator=(const GlyphsManager&) = delete; + + ~GlyphsManager(); + + int32_t GetRamUsedLen() const; + + int8_t GetFontVersion(char* version, uint8_t len) const; + + int16_t GetFontHeight() const; + + int16_t GetFontWidth(uint32_t unicode); + + const FontHeader* GetCurrentFontHeader() const; + + const GlyphNode* GetGlyphNode(uint32_t unicode); + + int8_t GetBitmap(uint32_t unicode, uint8_t* bitmap); + + void SetRamBuffer(uintptr_t ramAddr); + + int8_t SetFile(int32_t fp, uint32_t start); + + int8_t SetCurrentFontId(uint8_t fontId); + +private: + static constexpr uint8_t RADIX_TREE_BITS = 4; + static constexpr uint8_t RADIX_SHIFT_START = 32 - RADIX_TREE_BITS; + static constexpr uint32_t RADIX_TREE_SLOT_NUM = 1 << RADIX_TREE_BITS; + static constexpr uint32_t RADIX_TREE_MASK = RADIX_TREE_SLOT_NUM - 1; + + static constexpr uint8_t FONT_HASH_SHIFT = 3; + static constexpr uint8_t FONT_HASH_NR = 1 << FONT_HASH_SHIFT; + static constexpr uint32_t FONT_HASH_MASK = FONT_HASH_NR - 1; + static constexpr uint8_t UNICODE_HASH_SHIFT = 6; + static constexpr uint8_t UNICODE_HASH_NR = 1 << UNICODE_HASH_SHIFT; + static constexpr uint32_t UNICODE_HASH_MASK = UNICODE_HASH_NR - 1; + static constexpr uint8_t NODE_HASH_SHIFT = 4; + static constexpr uint8_t NODE_HASH_NR = 1 << NODE_HASH_SHIFT; + + using CacheType = GlyphNode[FONT_HASH_NR][UNICODE_HASH_NR][NODE_HASH_NR]; + using CacheState = uint8_t[FONT_HASH_NR][UNICODE_HASH_NR]; + + struct IndexNode { + uint16_t stubs[RADIX_TREE_SLOT_NUM]; + }; + + int8_t GlyphNodeCacheInit(); + GlyphNode* GetNodeFromCache(uint32_t unicode); + GlyphNode* GetNodeCacheSpace(uint32_t unicode); + GlyphNode* GetNodeFromFile(uint32_t unicode); + uint32_t AlignUp(uint32_t addr, uint32_t align) + { + return (((addr + (1 << align)) >> align) << align); + } + + BinHeader binHeader_; + uint8_t fontNum_; + uint32_t start_; + uint32_t fontHeaderSectionStart_; + uint32_t fontIndexSectionStart_; + uint32_t curFontIndexSectionStart_; + uint32_t glyphNodeSectionStart_; + uint32_t curGlyphNodeSectionStart_; + uint32_t bitMapSectionStart_; + uint32_t curBitMapSectionStart_; + + uint8_t* ramAddr_; + uint32_t ramUsedLen_; + FontHeader* fontHeaderCache_; + uint8_t* indexCache_; + uint8_t* curIndexCache_; + + CacheType* nodeCache_; + CacheState* cacheStatus_; + + int32_t fp_; + uint8_t fontId_; + FontHeader* curFontHeader_; + GlyphNode* curGlyphNode_; + + bool isRamSet_; + bool isFileSet_; + bool isFontIdSet_; +}; +} // namespace OHOS +#endif /* GLYPHS_MANAGER_FONT_H */ diff --git a/frameworks/font/ui_font.cpp b/frameworks/font/ui_font.cpp new file mode 100755 index 0000000..15c039f --- /dev/null +++ b/frameworks/font/ui_font.cpp @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "font/ui_font.h" +#include "common/text.h" +#include "font/ui_font_cache.h" +#if ENABLE_VECTOR_FONT +#include "font/ui_font_vector.h" +#endif // ENABLE_VECTOR_FONT +#include "graphic_config.h" +#if ENABLE_MULTI_FONT +#include "font/ui_multi_font_manager.h" +#endif + +namespace OHOS { +UIFont::UIFont() : instance_(nullptr), defaultInstance_(nullptr){}; + +UIFont::~UIFont(){}; + +UIFont* UIFont::GetInstance() +{ + static UIFont instance; +#if ENABLE_VECTOR_FONT + if (instance.instance_ == nullptr) { + instance.defaultInstance_ = new UIFontVector(); + instance.instance_ = instance.defaultInstance_; + } +#endif + return &instance; +} + +void UIFont::SetFont(BaseFont* font) +{ + if (font != nullptr) { + if (defaultInstance_ != nullptr) { + delete defaultInstance_; + defaultInstance_ = nullptr; + } + defaultInstance_ = font; + instance_ = font; + } +} + +uint8_t* UIFont::GetBitmap(uint32_t unicode, GlyphNode& glyphNode, uint8_t shapingFont) +{ + uint8_t* bitmap = nullptr; + uint8_t currentFontId = GetCurrentFontId(); +#if ENABLE_MULTI_FONT + // shaping font is in search list, search shaping font first + if (shapingFont > 1) { + bitmap = instance_->GetBitmap(unicode, glyphNode, shapingFont); + if (bitmap != nullptr) { + return bitmap; + } + } +#endif + bitmap = instance_->GetBitmap(unicode, glyphNode, currentFontId); + if (bitmap != nullptr) { + return bitmap; + } +#if ENABLE_MULTI_FONT + uint8_t* searchLists = nullptr; + int8_t listSize = UIMultiFontManager::GetInstance()->GetSearchFontList(currentFontId, &searchLists); + int8_t currentIndex = 0; + if ((searchLists == nullptr) || (listSize == 0)) { + return nullptr; + } + do { + SetCurrentFontId(searchLists[currentIndex], 0); + bitmap = instance_->GetBitmap(unicode, glyphNode, GetCurrentFontId()); + if (bitmap != nullptr) { + SetCurrentFontId(currentFontId, 0); + return bitmap; + } + // switch to next search List + currentIndex++; + } while ((currentIndex < listSize) && (searchLists != nullptr)); + SetCurrentFontId(currentFontId); +#endif + return nullptr; +} + +uint16_t UIFont::GetWidth(uint32_t unicode, uint8_t shapingId) +{ + int16_t result; + uint8_t currentFontId = GetCurrentFontId(); +#if ENABLE_MULTI_FONT + if (shapingId > 1) { + result = instance_->GetWidth(unicode, shapingId); + if (result >= 0) { + return result; + } + } +#endif + result = instance_->GetWidth(unicode, currentFontId); + if (result >= 0) { + return result; + } + +#if ENABLE_MULTI_FONT + uint8_t* searchLists = nullptr; + int8_t listSize = UIMultiFontManager::GetInstance()->GetSearchFontList(currentFontId, &searchLists); + if ((searchLists == nullptr) || (listSize == 0)) { + return 0; + } + int8_t currentIndex = 0; + do { + SetCurrentFontId(searchLists[currentIndex], 0); + result = instance_->GetWidth(unicode, GetCurrentFontId()); + if (result >= 0) { + SetCurrentFontId(currentFontId, 0); + return result; + } + currentIndex++; + } while ((currentIndex < listSize) && (searchLists != nullptr)); + SetCurrentFontId(currentFontId); +#endif + return 0; +} +} // namespace OHOS diff --git a/frameworks/font/ui_font_adaptor.cpp b/frameworks/font/ui_font_adaptor.cpp new file mode 100755 index 0000000..bb8912d --- /dev/null +++ b/frameworks/font/ui_font_adaptor.cpp @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "font/ui_font_adaptor.h" +#include "common/typed_text.h" +#include "graphic_config.h" +#if ENABLE_ICU +#include "font/ui_line_break.h" +#endif +#if ENABLE_SHAPING +#include "font/ui_text_shaping.h" +#endif +namespace OHOS { +uint32_t UIFontAdaptor::GetNextLineAndWidth(const char* txt, int16_t letterSpace, int16_t& maxWidth, bool allBreak) +{ +#if ENABLE_ICU + return UILineBreakEngine::GetInstance().GetNextLineAndWidth(txt, letterSpace, allBreak, maxWidth); +#else + uint32_t index = TypedText::GetNextLine(txt, letterSpace, maxWidth); + maxWidth = TypedText::GetTextWidth(txt, index, letterSpace); + return index; +#endif +} + +bool UIFontAdaptor::IsSameTTFId(uint8_t fontId, uint32_t unicode) +{ +#if ENABLE_SHAPING + return UITextShaping::IsSameTTFId(fontId, unicode); +#else + return true; +#endif +} +} // namespace OHOS + diff --git a/frameworks/font/ui_font_adaptor.h b/frameworks/font/ui_font_adaptor.h new file mode 100755 index 0000000..0bc1681 --- /dev/null +++ b/frameworks/font/ui_font_adaptor.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef UI_FONT_ADAPTOR +#define UI_FONT_ADAPTOR + +#include "common/typed_text.h" +#include "graphic_config.h" + +namespace OHOS { +class UIFontAdaptor : public HeapBase { +public: + static uint32_t GetNextLineAndWidth(const char* txt, int16_t letterSpace, int16_t& maxWidth, + bool allBreak = false); + + static bool IsSameTTFId(uint8_t fontId, uint32_t unicode); +}; +} // namespace OHOS +#endif // UI_FONT_ADAPTOR diff --git a/frameworks/font/ui_font_allocator.cpp b/frameworks/font/ui_font_allocator.cpp new file mode 100755 index 0000000..2e6a463 --- /dev/null +++ b/frameworks/font/ui_font_allocator.cpp @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "font/ui_font_allocator.h" + +namespace OHOS { +UIFontAllocator::UIFontAllocator() : ram_(nullptr), ramSize_(0), freeSize_(0), + minSize_(0), end_(nullptr), free_(nullptr) {} + +UIFontAllocator::~UIFontAllocator() {} + +void UIFontAllocator::SetRamAddr(uint8_t* ram, uint32_t size) +{ + struct Chunk* chunk = nullptr; + + ram_ = ram; + ramSize_ = size - sizeof(struct Chunk) * 2; // head and tail two chunk + chunk = reinterpret_cast(ram_); + chunk->next = size - sizeof(struct Chunk); + chunk->prev = 0; + chunk->used = false; + + end_ = reinterpret_cast(ram_ + size - sizeof(struct Chunk)); + end_->next = size - sizeof(struct Chunk); + end_->prev = size - sizeof(struct Chunk); + end_->used = true; + + free_ = chunk; + freeSize_ = size - sizeof(struct Chunk); +} + +uint32_t UIFontAllocator::GetSize(void *addr) +{ + struct Chunk *chunk = reinterpret_cast(static_cast(addr) - sizeof(struct Chunk)); + return chunk->next - (reinterpret_cast(addr) - reinterpret_cast(ram_)); +} + +void UIFontAllocator::SetMinChunkSize(uint32_t size) +{ + minSize_ = AlignSize(size); +} + +void* UIFontAllocator::Allocate(uint32_t size) +{ + uint32_t free, left; + uint32_t ptr, ptr2; + struct Chunk* chunk = nullptr; + struct Chunk* chunk2 = nullptr; + struct Chunk* chunk3 = nullptr; + + size = AlignSize(size); + if (size < minSize_) { + size = minSize_; + } + + for (ptr = reinterpret_cast(free_) - ram_; ptr < ramSize_; + ptr = reinterpret_cast(ram_ + ptr)->next) { + chunk = reinterpret_cast(ram_ + ptr); + if (chunk->used) { + continue; + } + free = chunk->next - ptr; + if (free < sizeof(struct Chunk) + size) { + continue; + } + left = free - sizeof(struct Chunk) - size; + if (left >= sizeof(struct Chunk) + minSize_) { + ptr2 = ptr + sizeof(struct Chunk) + size; + chunk2 = reinterpret_cast(ram_ + ptr2); + chunk2->used = false; + chunk2->next = chunk->next; + chunk2->prev = ptr; + chunk->next = ptr2; + chunk->used = true; + if (chunk2->next != end_->next) { + chunk3 = reinterpret_cast(ram_ + chunk2->next); + chunk3->prev = ptr2; + } + freeSize_ -= size + sizeof(struct Chunk); + } else { + chunk->used = true; + freeSize_ -= chunk->next - ptr; + } + + if (chunk == free_) { + struct Chunk* cur = free_; + while (cur->used && (cur != end_)) { + cur = reinterpret_cast(ram_ + cur->next); + } + free_ = cur; + } + + return reinterpret_cast(chunk) + sizeof(struct Chunk); + } + + return nullptr; +} + +void UIFontAllocator::CombineFree(struct Chunk* chunk) +{ + if (chunk == nullptr) { + return; + } + struct Chunk* nextChunk = nullptr; + struct Chunk* prevChunk = nullptr; + + nextChunk = reinterpret_cast(ram_ + chunk->next); + if (((nextChunk != chunk) && !(nextChunk->used)) && (nextChunk != end_)) { + if (free_ == nextChunk) { + free_ = chunk; + } + chunk->next = nextChunk->next; + reinterpret_cast(ram_ + nextChunk->next)->prev = reinterpret_cast(chunk) - ram_; + } + + prevChunk = reinterpret_cast(ram_ + chunk->prev); + if ((prevChunk != chunk) && !(prevChunk->used)) { + if (free_ == chunk) { + free_ = prevChunk; + } + prevChunk->next = chunk->next; + reinterpret_cast(ram_ + chunk->next)->prev = reinterpret_cast(prevChunk) - ram_; + } +} + +void UIFontAllocator::Free(void* addr) +{ + struct Chunk* chunk = nullptr; + + if (addr == nullptr) { + return; + } + + if ((reinterpret_cast(addr) < ram_) || + (reinterpret_cast(addr) > reinterpret_cast(end_))) { + return; + } + + chunk = reinterpret_cast(static_cast(addr) - sizeof(struct Chunk)); + chunk->used = false; + if (chunk < free_) { + free_ = chunk; + } + + freeSize_ += chunk->next - (reinterpret_cast(chunk) - ram_); + CombineFree(chunk); +} +} // namespace OHOS diff --git a/frameworks/font/ui_font_allocator.h b/frameworks/font/ui_font_allocator.h new file mode 100755 index 0000000..a846759 --- /dev/null +++ b/frameworks/font/ui_font_allocator.h @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef UI_FONT_ALLOCATOR_H +#define UI_FONT_ALLOCATOR_H + +#include + +namespace OHOS { +class UIFontAllocator { + static constexpr uint8_t MEM_ALIGNMENT = 4; + + struct Chunk { + uint32_t next; + uint32_t prev; + bool used; + }; + +public: + UIFontAllocator(); + + ~UIFontAllocator(); + + void SetRamAddr(uint8_t* ram, uint32_t size); + + void SetMinChunkSize(uint32_t size); + + uint32_t GetSize(void *addr); + + /** + * @brief allocate memory + * + * @param size + * @return memory address + */ + void *Allocate(uint32_t size); + + void Free(void* addr); + +private: + uint32_t AlignSize(uint32_t size) + { + return (size + MEM_ALIGNMENT - 1U) & ~(MEM_ALIGNMENT - 1U); + } + void CombineFree(Chunk* cache); + + uint8_t* ram_; + uint32_t ramSize_; + uint32_t freeSize_; + uint32_t minSize_; + struct Chunk* end_; + struct Chunk* free_; +}; +} // namespace OHOS +#endif /* UI_FONT_ALLOCATOR_H */ \ No newline at end of file diff --git a/frameworks/font/ui_font_cache.cpp b/frameworks/font/ui_font_cache.cpp new file mode 100755 index 0000000..decc66e --- /dev/null +++ b/frameworks/font/ui_font_cache.cpp @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "font/ui_font_cache.h" +#include + +namespace OHOS { +UIFontCache::UIFontCache(uint8_t* ram, uint32_t size) +{ + if (ram == nullptr) { + return; + } + allocator_.SetRamAddr(ram, size); + allocator_.SetMinChunkSize(FONT_CACHE_MIN_SIZE + sizeof(Bitmap)); + + uint32_t hashTableSize = sizeof(ListHead) * FONT_CACHE_HASH_NR; + hashTable_ = reinterpret_cast(allocator_.Allocate(hashTableSize)); + for (uint8_t i = 0; i < FONT_CACHE_HASH_NR; i++) { + ListInit(hashTable_ + i); + } + + ListInit(&lruList_); +} + +UIFontCache::~UIFontCache() {} + +void UIFontCache::UpdateLru(Bitmap* bitmap) +{ + ListDel(&bitmap->lruHead); + ListInit(&bitmap->lruHead); + ListAdd(&bitmap->lruHead, &lruList_); +} + +uint8_t* UIFontCache::GetSpace(uint8_t fontId, uint32_t unicode, uint32_t size) +{ + Bitmap* bitmap = nullptr; + + uint32_t allocSize = sizeof(Bitmap) + size; + while (bitmap == nullptr) { + bitmap = reinterpret_cast(allocator_.Allocate(allocSize)); + if (bitmap == nullptr) { + // nothing to free, return null + if ((lruList_.prev == &lruList_) && (lruList_.next == &lruList_)) { + return nullptr; + } + Bitmap* toFree = reinterpret_cast(reinterpret_cast(lruList_.prev) - + offsetof(struct Bitmap, lruHead)); + ListDel(&toFree->hashHead); + ListDel(&toFree->lruHead); + allocator_.Free(toFree); + } + } + + ListInit(&bitmap->hashHead); + ListInit(&bitmap->lruHead); + ListAdd(&bitmap->hashHead, hashTable_ + fontId % FONT_CACHE_HASH_NR); + ListAdd(&bitmap->lruHead, &lruList_); + + bitmap->fontId = fontId; + bitmap->unicode = unicode; + + return reinterpret_cast(bitmap->data); +} + +void UIFontCache::PutSpace(uint8_t* addr) +{ + if (addr == nullptr) { + return; + } + Bitmap* bitmap = reinterpret_cast(addr - sizeof(Bitmap)); + + ListDel(&bitmap->hashHead); + ListDel(&bitmap->lruHead); + + allocator_.Free(bitmap); +} + +uint8_t* UIFontCache::GetBitmap(uint8_t fontId, uint32_t unicode) +{ + Bitmap* bitmap = nullptr; + ListHead* node = nullptr; + ListHead* head = hashTable_ + fontId % FONT_CACHE_HASH_NR; + for (node = head->next; node != head; node = node->next) { + bitmap = reinterpret_cast(reinterpret_cast(node) - + offsetof(struct Bitmap, hashHead)); + if ((bitmap->fontId == fontId) && (bitmap->unicode == unicode)) { + UpdateLru(bitmap); + return reinterpret_cast(bitmap->data); + } + } + + return nullptr; +} +} // namespace OHOS diff --git a/frameworks/font/ui_font_cache.h b/frameworks/font/ui_font_cache.h new file mode 100755 index 0000000..fc9b2b0 --- /dev/null +++ b/frameworks/font/ui_font_cache.h @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef UI_FONT_CACHE_H +#define UI_FONT_CACHE_H + +#include "ui_font_allocator.h" + +namespace OHOS { +class UIFontCache { +public: + static constexpr uint8_t FONT_CACHE_HASH_NR = 32; + static constexpr uint32_t FONT_CACHE_MIN_SIZE = 20 * 20; + struct ListHead { + ListHead* prev; + ListHead* next; + }; + struct Bitmap { + ListHead hashHead; + ListHead lruHead; + uint8_t fontId; + uint32_t unicode; + uint8_t data[]; + }; + + UIFontCache(uint8_t* ram, uint32_t size); + + ~UIFontCache(); + + uint8_t* GetSpace(uint8_t fontId, uint32_t unicode, uint32_t size); + + void PutSpace(uint8_t* addr); + + uint8_t* GetBitmap(uint8_t fontId, uint32_t unicode); + +private: + void UpdateLru(Bitmap* bitmap); + void ListInit(ListHead* head) + { + head->prev = head; + head->next = head; + } + void ListAdd(ListHead* node, ListHead* head) + { + head->next->prev = node; + node->next = head->next; + node->prev = head; + head->next = node; + } + void ListDel(ListHead* node) + { + node->next->prev = node->prev; + node->prev->next = node->next; + } + + UIFontAllocator allocator_; + ListHead* hashTable_ = nullptr; + ListHead lruList_ = {}; +}; +} // namespace OHOS +#endif /* UI_FONT_CACHE_H */ \ No newline at end of file diff --git a/frameworks/font/ui_font_vector.cpp b/frameworks/font/ui_font_vector.cpp new file mode 100755 index 0000000..2d79d65 --- /dev/null +++ b/frameworks/font/ui_font_vector.cpp @@ -0,0 +1,428 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "font/ui_font_vector.h" +#include "file.h" +#include "graphic_config.h" +#include "securec.h" +#if ENABLE_MULTI_FONT +#include "font/ui_multi_font_manager.h" +#endif + +namespace OHOS { +UIFontVector::UIFontVector() +{ +#ifdef _WIN32 + ttfDir_ = _pgmptr; + size_t len = ttfDir_.size(); + size_t pos = ttfDir_.find_last_of('\\'); + if (pos != std::string::npos) { + ttfDir_.replace((pos + 1), (len - pos), VECTOR_FONT_DIR); + } +#else + ttfDir_ = VECTOR_FONT_DIR; +#endif // _WIN32 + ftLibrary_ = nullptr; + freeTypeInited_ = ((FT_Init_FreeType(&ftLibrary_) == 0) ? true : false); + SetBaseFontId(FONT_ID_MAX); + bitmapCache_ = nullptr; +} + +UIFontVector::~UIFontVector() +{ + if (freeTypeInited_) { + FT_Done_FreeType(ftLibrary_); + freeTypeInited_ = false; + UnregisterFontInfo(DEFAULT_VECTOR_FONT_FILENAME); + } + delete bitmapCache_; +} + +uint8_t UIFontVector::RegisterFontInfo(const char* ttfName, uint8_t shaping) +{ + if ((ttfName == nullptr) || !freeTypeInited_) { + return FONT_INVALID_TTF_ID; + } + int32_t j = 0; + while (j < FONT_ID_MAX) { + if ((fontInfo_[j].ttfName != nullptr) && !strncmp(fontInfo_[j].ttfName, ttfName, TTF_NAME_LEN_MAX)) { + return j; + } else if (fontInfo_[j].ttfName == nullptr) { + std::string ttfPath = ttfDir_; + ttfPath.append(ttfName); + int32_t error = FT_New_Face(ftLibrary_, ttfPath.c_str(), 0, &ftFaces_[j]); + if (error != 0) { + return FONT_INVALID_TTF_ID; + } + fontInfo_[j].ttfName = ttfName; + fontInfo_[j].shaping = shaping; + fontInfo_[j].ttfId = j; +#if ENABLE_MULTI_FONT + UIMultiFontManager::GetInstance()->UpdateScript(fontInfo_[j]); +#endif + return j; + } + j++; + } + return FONT_INVALID_TTF_ID; +} + +uint8_t UIFontVector::RegisterFontInfo(const UITextLanguageFontParam* fontsTable, uint8_t num) +{ + if (fontsTable == nullptr) { + return FONT_INVALID_TTF_ID; + } + uint8_t count = 0; + for (int i = 0; i < num; i++) { + uint8_t result = RegisterFontInfo(fontsTable[i].ttfName, fontsTable[i].shaping); + if (result == FONT_INVALID_TTF_ID) { + continue; + } + count++; + } + return count; +} + +uint8_t UIFontVector::UnregisterFontInfo(const UITextLanguageFontParam* fontsTable, uint8_t num) +{ + if (fontsTable == nullptr) { + return 0; + } + uint8_t count = 0; + for (int i = 0; i < num; i++) { + uint8_t result = UnregisterFontInfo(fontsTable[i].ttfName); + if (result == FONT_INVALID_TTF_ID) { + return FONT_INVALID_TTF_ID; + } + count++; + } + return count; +} +uint8_t UIFontVector::UnregisterFontInfo(const char* ttfName) +{ + if (ttfName != nullptr) { + int32_t i = 0; + while (i < FONT_ID_MAX) { + if ((fontInfo_[i].ttfName != nullptr) && !strncmp(fontInfo_[i].ttfName, ttfName, TTF_NAME_LEN_MAX)) { + fontInfo_[i].ttfName = nullptr; + FT_Done_Face(ftFaces_[i]); + ftFaces_[i] = nullptr; + return static_cast(i); + } + i++; + } + } + return FONT_INVALID_TTF_ID; +} + +const UITextLanguageFontParam* UIFontVector::GetFontInfo(uint8_t fontId) const +{ + if (fontId < FONT_ID_MAX) { + return static_cast(&fontInfo_[fontId]); + } + return nullptr; +} + +int32_t UIFontVector::OpenVectorFont(uint8_t ttfId) +{ + int32_t i = 0; + int32_t fp = 0; + while (i < FONT_ID_MAX) { + if (fontInfo_[i].ttfName == nullptr) { + i++; + continue; + } + if (fontInfo_[i].ttfId == ttfId) { + std::string ttfPath = ttfDir_; + ttfPath.append(fontInfo_[i].ttfName); +#ifdef _WIN32 + fp = open(ttfPath.c_str(), O_RDONLY | O_BINARY); +#else + fp = open(ttfPath.c_str(), O_RDONLY); +#endif + return fp; + } + i++; + } + return -1; +} + +bool UIFontVector::IsVectorFont() const +{ + return true; +} + +uint8_t UIFontVector::GetFontWeight(uint8_t fontId) +{ + return FONT_BPP_8; +} + +int8_t UIFontVector::SetFontPath(const char* dpath, const char* spath) +{ + if (dpath == nullptr) { + return INVALID_RET_VALUE; + } + ttfDir_ = dpath; + return RET_VALUE_OK; +} + +int8_t UIFontVector::SetCurrentFontId(uint8_t fontId, uint8_t size) +{ + if (size == 0) { + size = key_ & 0xFF; // the last 8bit is size + } + if ((fontId >= FONT_ID_MAX) || (size == 0)) { + return INVALID_RET_VALUE; + } + const UITextLanguageFontParam* fontInfo = GetFontInfo(fontId); + if ((fontInfo == nullptr) || (fontInfo->ttfName == nullptr)) { + return INVALID_RET_VALUE; + } + uint32_t key = GetKey(fontId, size); + if (key_ == key) { + return RET_VALUE_OK; + } + + if (!freeTypeInited_) { + return INVALID_RET_VALUE; + } + + // Set the size + int error = FT_Set_Char_Size(ftFaces_[fontId], size * FONT_PIXEL_IN_POINT, 0, 0, 0); + if (error != 0) { + return INVALID_RET_VALUE; + } + key_ = key; + SetBaseFontId(fontId); + uintptr_t ramAddr_ = GetRamAddr(); + uint32_t ramLen_ = GetRamLen(); + if (bitmapCache_ == nullptr) { + bitmapCache_ = new(std::nothrow) UIFontCache(reinterpret_cast(ramAddr_), ramLen_); + if (bitmapCache_ == nullptr) { + return INVALID_RET_VALUE; + } + } + return RET_VALUE_OK; +} + +uint16_t UIFontVector::GetHeight() +{ + uint8_t fontId_ = GetBaseFontId(); + if (!freeTypeInited_ || (ftFaces_[fontId_] == nullptr) || (bitmapCache_ == nullptr)) { + return 0; + } + return static_cast(ftFaces_[fontId_]->size->metrics.height / FONT_PIXEL_IN_POINT); +} + +uint8_t UIFontVector::GetShapingFontId(char* text, uint8_t& ttfId, uint32_t& script, uint8_t fontId, uint8_t size) const +{ +#if ENABLE_MULTI_FONT + const UITextLanguageFontParam* fontParam1 = GetFontInfo(fontId); + if (fontParam1 == nullptr) { + return 0; + } + if (fontParam1->shaping == 0) { + if (!UIMultiFontManager::GetInstance()->IsNeedShaping(text, ttfId, script)) { + return 0; // 0 means no need to shape + } + uint8_t* searchLists = nullptr; + int8_t length = UIMultiFontManager::GetInstance()->GetSearchFontList(fontId, &searchLists); + const UITextLanguageFontParam* fontParam2 = nullptr; + for (uint8_t i = 0; i < length; i++) { + fontParam2 = GetFontInfo(searchLists[i]); + if (fontParam2 == nullptr) { + continue; + } + if (fontParam2->ttfId == ttfId) { + return fontParam2->shaping; + } + } + return 0; + } + ttfId = fontParam1->ttfId; + +#if ENABLE_SHAPING + script = UIMultiFontManager::GetInstance()->GetScriptByTtfId(ttfId); +#endif + return fontParam1->shaping; +#else + const UITextLanguageFontParam* fontInfo = GetFontInfo(fontId); + if (fontInfo == nullptr) { + return 0; + } + ttfId = fontInfo->ttfId; + return fontInfo->shaping; +#endif +} +uint8_t UIFontVector::GetFontId(const char* ttfName, uint8_t size) const +{ + if (ttfName != nullptr) { + int32_t i = 0; + while (i < FONT_ID_MAX) { + if ((fontInfo_[i].ttfName != nullptr) && (strstr(fontInfo_[i].ttfName, ttfName) != nullptr)) { + return static_cast(i); + } + i++; + } + } + + return FONT_ID_MAX; +} + +uint8_t UIFontVector::GetFontId(uint32_t unicode) const +{ + int32_t i = 0; + uint8_t ttfId = ((unicode >> 24) & 0x1F); // 24: Whether 25 ~29 bit storage is ttfId 0x1F:5bit + while (i < FONT_ID_MAX) { + if (fontInfo_[i].ttfName == nullptr) { + i++; + continue; + } + if (fontInfo_[i].ttfId == ttfId) { + return i; + } + i++; + } + return FONT_INVALID_TTF_ID; +} + +int16_t UIFontVector::GetWidth(uint32_t unicode, uint8_t fontId) +{ + if (!freeTypeInited_ || (ftFaces_[fontId] == nullptr) || (bitmapCache_ == nullptr)) { + return INVALID_RET_VALUE; + } + uint8_t* bitmap = bitmapCache_->GetBitmap(key_, unicode); + if (bitmap != nullptr) { + return reinterpret_cast(bitmap)->advance; + } + + int8_t error = LoadGlyphIntoFace(fontId, unicode); + if (error != RET_VALUE_OK) { + return INVALID_RET_VALUE; + } + SetFace(ftFaces_[fontId], unicode); + return static_cast(ftFaces_[fontId]->glyph->advance.x / FONT_PIXEL_IN_POINT); +} + +int8_t UIFontVector::GetCurrentFontHeader(FontHeader& fontHeader) +{ + uint8_t fontId_ = GetBaseFontId(); + if (!freeTypeInited_ || (ftFaces_[fontId_] == nullptr) || (bitmapCache_ == nullptr)) { + return INVALID_RET_VALUE; + } + + fontHeader.ascender = static_cast(ftFaces_[fontId_]->size->metrics.ascender / FONT_PIXEL_IN_POINT); + fontHeader.descender = static_cast(ftFaces_[fontId_]->size->metrics.descender / FONT_PIXEL_IN_POINT); + fontHeader.fontHeight = static_cast(ftFaces_[fontId_]->size->metrics.height / FONT_PIXEL_IN_POINT); + return RET_VALUE_OK; +} + +int8_t UIFontVector::GetGlyphNode(uint32_t unicode, GlyphNode& glyphNode) +{ + uint8_t fontId_ = GetBaseFontId(); + if (!freeTypeInited_ || (ftFaces_[fontId_] == nullptr) || (bitmapCache_ == nullptr)) { + return INVALID_RET_VALUE; + } + uint8_t* bitmap = bitmapCache_->GetBitmap(key_, unicode); + if (bitmap != nullptr) { + Metric* f = reinterpret_cast(bitmap); + glyphNode.left = f->left; + glyphNode.top = f->top; + glyphNode.cols = f->cols; + glyphNode.rows = f->rows; + glyphNode.advance = f->advance; + return RET_VALUE_OK; + } + int8_t error = LoadGlyphIntoFace(fontId_, unicode); + if (error != RET_VALUE_OK) { + return INVALID_RET_VALUE; + } + + glyphNode.left = ftFaces_[fontId_]->glyph->bitmap_left; + glyphNode.top = ftFaces_[fontId_]->glyph->bitmap_top; + glyphNode.cols = ftFaces_[fontId_]->glyph->bitmap.width; + glyphNode.rows = ftFaces_[fontId_]->glyph->bitmap.rows; + glyphNode.advance = static_cast(ftFaces_[fontId_]->glyph->advance.x / FONT_PIXEL_IN_POINT); + SetFace(ftFaces_[fontId_], unicode); + return RET_VALUE_OK; +} + +uint8_t* UIFontVector::GetBitmap(uint32_t unicode, GlyphNode& glyphNode, uint8_t fontId) +{ + if (GetGlyphNode(unicode, glyphNode) != RET_VALUE_OK) { + return nullptr; + } + uint8_t* bitmap = bitmapCache_->GetBitmap(key_, unicode); + if (bitmap != nullptr) { + return bitmap + sizeof(Metric); + } + SetFace(ftFaces_[fontId], unicode); + return static_cast(ftFaces_[fontId]->glyph->bitmap.buffer); +} + +int8_t UIFontVector::LoadGlyphIntoFace(uint8_t fontId, uint32_t unicode) +{ + int32_t error; + if (IsGlyphFont(unicode) != 0) { + if (fontId != GetFontId(unicode)) { + return INVALID_RET_VALUE; + } + unicode = unicode & (0xFFFFFF); // Whether 0 ~24 bit storage is unicode + error = FT_Load_Glyph(ftFaces_[fontId], unicode, FT_LOAD_RENDER); + } else { + error = FT_Load_Char(ftFaces_[fontId], unicode, FT_LOAD_RENDER); + } + if ((error != 0) || (ftFaces_[fontId]->glyph->glyph_index == 0)) { + return INVALID_RET_VALUE; + } + return RET_VALUE_OK; +} + +uint8_t UIFontVector::IsGlyphFont(uint32_t unicode) +{ + uint8_t unicodeFontId = GetFontId(unicode); + if (unicodeFontId == FONT_INVALID_TTF_ID) { + return 0; + } else { + return fontInfo_[unicodeFontId].shaping; + } +} + +void UIFontVector::SetFace(FT_Face ftFace, uint32_t unicode) const +{ + Metric f; + f.advance = static_cast(ftFace->glyph->advance.x / FONT_PIXEL_IN_POINT); + f.left = ftFace->glyph->bitmap_left; + f.top = ftFace->glyph->bitmap_top; + f.cols = ftFace->glyph->bitmap.width; + f.rows = ftFace->glyph->bitmap.rows; + + uint32_t bitmapSize = ftFace->glyph->bitmap.width * ftFace->glyph->bitmap.rows; + uint8_t* bitmap = bitmapCache_->GetSpace(key_, unicode, bitmapSize + sizeof(Metric)); + if (bitmap != nullptr) { + if (memcpy_s(bitmap, sizeof(Metric), &f, sizeof(Metric)) != EOK) { + return; + } + if (memcpy_s(bitmap + sizeof(Metric), bitmapSize, ftFace->glyph->bitmap.buffer, bitmapSize) != EOK) { + return; + } + } +} + +inline uint32_t UIFontVector::GetKey(uint8_t fontId, uint32_t size) +{ + return ((static_cast(fontId)) << 24) + size; // fontId store at the (24+1)th bit +} +} // namespace OHOS diff --git a/frameworks/font/ui_line_break.cpp b/frameworks/font/ui_line_break.cpp new file mode 100755 index 0000000..edda071 --- /dev/null +++ b/frameworks/font/ui_line_break.cpp @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#if ENABLE_ICU +#include "font/ui_line_break.h" +namespace OHOS { +UILineBreakEngine* UILineBreakEngine::instance_ = nullptr; +uint32_t UILineBreakEngine::GetNextLineAndWidth(const char* txt, int16_t space, bool allBreak, int16_t &maxWidth, + uint16_t len) +{ + // Need to be implemented + return 0; +} +} // namespace OHOS +#endif // ENABLE_ICU \ No newline at end of file diff --git a/frameworks/font/ui_line_break.h b/frameworks/font/ui_line_break.h new file mode 100755 index 0000000..b1c3a14 --- /dev/null +++ b/frameworks/font/ui_line_break.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef GRAPHIC_LITE_LINE_BREAK_H +#define GRAPHIC_LITE_LINE_BREAK_H + +#include "graphic_config.h" +#if ENABLE_ICU +#include "font/ui_font_header.h" +#include +#include +namespace OHOS { +/** + * @brief line break engine.Use ICU as core. + * + * @since 1.0 + * @version 1.0 + */ +class UILineBreakEngine : public HeapBase { +public: + /** + * @brief Get the Instance object + * + * @return UILineBreakEngine& + * @since 1.0 + * @version 1.0 + */ + static UILineBreakEngine& GetInstance() + { + if (instance_ == nullptr) { + instance_ = new UILineBreakEngine(); + } + return *instance_; + } + + // 0xFFFF: unlimit the length until the end null. + uint32_t GetNextLineAndWidth(const char* txt, + int16_t space, + bool allBreak, + int16_t &maxWidth, + uint16_t len = 0xFFFF); +private: + static UILineBreakEngine* instance_; + UILineBreakEngine() {} + ~UILineBreakEngine() {} +}; +} // namespace OHOS +#endif // ENABLE_ICU +#endif // GRAPHIC_LITE_LINE_BREAK_H diff --git a/frameworks/font/ui_multi_font_manager.cpp b/frameworks/font/ui_multi_font_manager.cpp new file mode 100755 index 0000000..d559eb6 --- /dev/null +++ b/frameworks/font/ui_multi_font_manager.cpp @@ -0,0 +1,273 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "font/ui_multi_font_manager.h" +#include "common/typed_text.h" +#include "font/ui_font.h" + +#include "mem_api.h" +#include "securec.h" +#if ENABLE_SHAPING +#include "font/ui_text_shaping.h" +#endif +#if ENABLE_MULTI_FONT +namespace OHOS { +UIMultiFontManager::UIMultiFontManager() + : arbicTtfId_(0), thaiTtfId_(0), myanmarTtfId_(0), + devanagariTtfId_(0), hebrewTtfId_(0), + bengaliTtfId_(0), topIndex_(0) +{ + const UITextLanguageFontParam* fontParam = nullptr; + uint8_t totalFontId = GetTotalFontId(); + for (uint8_t i = 0; i < totalFontId; i++) { + fontParam = UIFont::GetInstance()->GetFontInfo(i); + if (fontParam == nullptr) { + continue; + } + if (!fontParam->shaping) { + continue; + } + if (strstr(fontParam->ttfName, ARABIC_LANG) != nullptr) { + arbicTtfId_ = fontParam->ttfId; + } else if (strstr(fontParam->ttfName, THAI_LANG) != nullptr) { + thaiTtfId_ = fontParam->ttfId; + } else if (strstr(fontParam->ttfName, MYAN_LANG) != nullptr) { + myanmarTtfId_ = fontParam->ttfId; + } else if (strstr(fontParam->ttfName, DVCARI_LANG) != nullptr) { + devanagariTtfId_ = fontParam->ttfId; + } else if (strstr(fontParam->ttfName, HBREW_LANG) != nullptr) { + hebrewTtfId_ = fontParam->ttfId; + } else if (strstr(fontParam->ttfName, BENGALI_LANG) != nullptr) { + bengaliTtfId_ = fontParam->ttfId; + } + } + fontIdIndex_ = static_cast(UIMalloc(totalFontId)); + if (fontIdIndex_ == nullptr) { + return; + } + for (uint8_t index = 0; index < totalFontId; index++) { + fontIdIndex_[index] = MAX_LIST_NUM; + } + for (uint8_t index = 0; index < MAX_LIST_NUM; index++) { + fontNodes_[index].fontIds = nullptr; + fontNodes_[index].size = 0; + } +} + +UIMultiFontManager::~UIMultiFontManager() +{ + UIFree(fontIdIndex_); + fontIdIndex_ = nullptr; +} + + +int8_t UIMultiFontManager::AddNewFont(uint8_t fontListId, uint8_t *fontIds, int8_t size, uint8_t fontId) +{ + fontNodes_[fontId].fontIds = static_cast(UIMalloc(size)); + if (fontNodes_[fontId].fontIds == nullptr) { + return fontId; + } + fontIdIndex_[fontListId] = fontId; + (void)memcpy_s(fontNodes_[fontId].fontIds, size, fontIds, size); + fontNodes_[fontId].size = size; + return fontId + 1; +} + +int8_t UIMultiFontManager::UpdateFont(uint8_t fontListId, uint8_t *fontIds, uint8_t size) +{ + uint8_t index = fontIdIndex_[fontListId]; + if (index < topIndex_) { + UIFree(fontNodes_[index].fontIds); + fontNodes_[index].fontIds = nullptr; + } else { + index = topIndex_; + } + + uint8_t nextIndex = AddNewFont(fontListId, fontIds, size, index); + if (topIndex_ < nextIndex) { + topIndex_ = nextIndex; + } + return (fontNodes_[index].fontIds == nullptr) ? INVALID_RET_VALUE : RET_VALUE_OK; +} + +void UIMultiFontManager::UpdateScript(UITextLanguageFontParam& fonts) +{ + if (strstr(fonts.ttfName, ARABIC_LANG) != nullptr) { + arbicTtfId_ = fonts.ttfId; + } else if (strstr(fonts.ttfName, THAI_LANG) != nullptr) { + thaiTtfId_ = fonts.ttfId; + } else if (strstr(fonts.ttfName, MYAN_LANG) != nullptr) { + myanmarTtfId_ = fonts.ttfId; + } else if (strstr(fonts.ttfName, DVCARI_LANG) != nullptr) { + devanagariTtfId_ = fonts.ttfId; + } else if (strstr(fonts.ttfName, HBREW_LANG) != nullptr) { + hebrewTtfId_ = fonts.ttfId; + } else if (strstr(fonts.ttfName, BENGALI_LANG) != nullptr) { + bengaliTtfId_ = fonts.ttfId; + } +} + +void UIMultiFontManager::ClearSearchFontList() +{ + uint8_t totalFontId = GetTotalFontId(); + for (uint8_t index = 0; index < totalFontId; index++) { + fontIdIndex_[index] = MAX_LIST_NUM; + } + + for (auto &node : fontNodes_) { + UIFree(node.fontIds); + node.fontIds = nullptr; + node.size = 0; + } + topIndex_ = 0; +} + +int8_t UIMultiFontManager::SetSearchFontList(uint8_t fontListId, uint8_t *fontIds, uint8_t size) +{ + if ((fontListId >= GetTotalFontId()) || (fontIds == nullptr) || (size == 0) || + (fontIdIndex_ == nullptr) || (topIndex_ >= MAX_LIST_NUM)) { + return INVALID_RET_VALUE; + } + // update + return UpdateFont(fontListId, fontIds, size); +} + +int8_t UIMultiFontManager::GetSearchFontList(uint8_t fontListId, uint8_t **fontIds) +{ + if ((fontListId >= GetTotalFontId()) || (fontIds == nullptr) || + (fontIdIndex_ == nullptr) || (fontIdIndex_[fontListId] >= MAX_LIST_NUM)) { + return INVALID_RET_VALUE; + } + *fontIds = fontNodes_[fontIdIndex_[fontListId]].fontIds; + return fontNodes_[fontIdIndex_[fontListId]].size; +} + +bool UIMultiFontManager::IsNeedShaping(const char *text, uint8_t &ttfId, uint32_t &script) +{ + if (text == nullptr) { + return false; + } + + uint32_t i = 0; + while (text[i] != '\0') { + uint32_t unicode = TypedText::GetUTF8Next(text, i, i); + if (IsShapingLetter(unicode, ttfId)) { +#if ENABLE_SHAPING + script = GetScriptByTtfId(ttfId); +#endif + return true; + } + } + return false; +} + +uint8_t UIMultiFontManager::GetShapingFontId(const char* text, uint8_t fontId, uint8_t& ttfId, uint32_t& script) +{ + // the shaping font is in search list, then shapingFontId_ store the real shaping fontid + const UITextLanguageFontParam* fontParam1 = UIFont::GetInstance()->GetFontInfo(fontId); + if (fontParam1 == nullptr) { + return DEFAULT_SHAPING_ID; + } + if (!fontParam1->shaping) { + if (!IsNeedShaping(text, ttfId, script)) { + return 0; // 0 means no need to shape + } + uint8_t* searchLists = nullptr; + int8_t length = GetSearchFontList(fontId, &searchLists); + const UITextLanguageFontParam* fontParam2 = nullptr; + for (uint8_t i = 0; i < length; i++) { + fontParam2 = UIFont::GetInstance()->GetFontInfo(searchLists[i]); + if (fontParam2 == nullptr) { + continue; + } + if (fontParam2->ttfId == ttfId) { + return searchLists[i]; + } + } + return 0; + } + ttfId = fontParam1->ttfId; + +#if ENABLE_SHAPING + script = GetScriptByTtfId(ttfId); +#endif + return DEFAULT_SHAPING_ID; +} +int8_t UIMultiFontManager::IsShapingLetter(uint32_t unicode, uint8_t &ttfId) +{ + // arbic + if ((unicode <= 0x06FF) && (unicode >= 0x0600)) { + ttfId = arbicTtfId_; + return ttfId != 0; + } + // thai + if ((unicode <= 0x0E7F) && (unicode >= 0x0E00)) { + ttfId = thaiTtfId_; + return ttfId != 0; + } + // Devanagari + if ((unicode <= 0x097F) && (unicode >= 0x0900)) { + ttfId = devanagariTtfId_; + return ttfId != 0; + } + // Hebrew + if ((unicode <= 0x05FF) && (unicode >= 0x0590)) { + ttfId = hebrewTtfId_; + return ttfId != 0; + } + // Myanmar + if ((unicode <= 0x109F) && (unicode >= 0x1000)) { + ttfId = myanmarTtfId_; + return ttfId != 0; + } + // Bengali + if ((unicode <= 0x9FF) && (unicode >= 0x980)) { + ttfId = bengaliTtfId_; + return ttfId != 0; + } + return false; +} +#if ENABLE_SHAPING +uint32_t UIMultiFontManager::GetScriptByTtfId(uint8_t ttfId) +{ + // arbic + if (ttfId == arbicTtfId_) { + return SHAPING_SCRIPT_ARABIC; + } + // thai + if (ttfId == thaiTtfId_) { + return SHAPING_SCRIPT_THAI; + } + // Devanagari + if (ttfId == devanagariTtfId_) { + return SHAPING_SCRIPT_DEVANAGARI; + } + // Hebrew + if (ttfId == hebrewTtfId_) { + return SHAPING_SCRIPT_HEBREW; + } + // Myanmar + if (ttfId == myanmarTtfId_) { + return SHAPING_SCRIPT_MYANMAR; + } + // Bengali + if (ttfId == bengaliTtfId_) { + return SHAPING_SCRIPT_BENGALI; + } + return SHAPING_SCRIPT_INVALID; +} +#endif +} +#endif diff --git a/frameworks/font/ui_multi_font_manager.h b/frameworks/font/ui_multi_font_manager.h new file mode 100755 index 0000000..05a3964 --- /dev/null +++ b/frameworks/font/ui_multi_font_manager.h @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef UI_MULTI_FONT_MANAGER_H +#define UI_MULTI_FONT_MANAGER_H + +#include "graphic_config.h" +#include "font/ui_font_header.h" +#if ENABLE_MULTI_FONT +namespace OHOS { +class UIMultiFontManager : public HeapBase { +public: + UIMultiFontManager(const UIMultiFontManager &) = delete; + UIMultiFontManager& operator=(const UIMultiFontManager &) = delete; + UIMultiFontManager(UIMultiFontManager &&) noexcept = delete; + UIMultiFontManager& operator=(UIMultiFontManager &&) noexcept = delete; + + /** + * @brief Get the Instance object + * + * @return UIMultiFontManager* + */ + static UIMultiFontManager *GetInstance() + { + static UIMultiFontManager instance; + return &instance; + } + + void ClearSearchFontList(); + int8_t SetSearchFontList(uint8_t fontListId, uint8_t *fontIds, uint8_t size); + int8_t GetSearchFontList(uint8_t fontListId, uint8_t **fontIds); + void UpdateScript(UITextLanguageFontParam& fonts); + bool IsNeedShaping(const char* text, uint8_t& ttfId, uint32_t& script); + uint8_t GetShapingFontId(const char* text, uint8_t fontId, uint8_t& ttfId, uint32_t& script); +#if ENABLE_SHAPING + uint32_t GetScriptByTtfId(uint8_t ttfId); +#endif + +private: + /** + * @brief Construct a new UIMultiFontManager object + * + */ + UIMultiFontManager(); + + /** + * @brief Destroy the UIMultiFontManager object + * + */ + ~UIMultiFontManager(); + int8_t AddNewFont(uint8_t fontListId, uint8_t *fontIds, int8_t size, uint8_t fontId); + int8_t UpdateFont(uint8_t fontListId, uint8_t *fontIds, uint8_t size); + int8_t IsShapingLetter(uint32_t unicode, uint8_t& ttfId); + struct FontIdNode { + uint8_t* fontIds = nullptr; + int8_t size = 0; + }; + static constexpr uint8_t MAX_LIST_NUM = 20; + static constexpr uint8_t DEFAULT_SHAPING_ID = 1; + static constexpr const char *ARABIC_LANG = "Arabic"; + static constexpr const char *THAI_LANG = "Thai"; + static constexpr const char *MYAN_LANG = "Myanmar"; + static constexpr const char *DVCARI_LANG = "Devanagari"; + static constexpr const char *HBREW_LANG = "Hebrew"; + static constexpr const char *BENGALI_LANG = "Bengali"; + uint8_t arbicTtfId_; + uint8_t thaiTtfId_; + uint8_t myanmarTtfId_; + uint8_t devanagariTtfId_; + uint8_t hebrewTtfId_; + uint8_t bengaliTtfId_; + uint8_t topIndex_; + uint8_t* fontIdIndex_; + FontIdNode fontNodes_[MAX_LIST_NUM]; +}; +} +#endif +#endif \ No newline at end of file diff --git a/frameworks/font/ui_text_shaping.cpp b/frameworks/font/ui_text_shaping.cpp new file mode 100755 index 0000000..8f1f701 --- /dev/null +++ b/frameworks/font/ui_text_shaping.cpp @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#if ENABLE_SHAPING +#include "font/ui_text_shaping.h" + +namespace OHOS { +bool UITextShaping::IsSameTTFId(uint8_t fontId, uint32_t unicode) +{ + // Need to be implemented + return false; +} +} // namespace OHOS +#endif /* ENABLE_SHAPING */ diff --git a/frameworks/font/ui_text_shaping.h b/frameworks/font/ui_text_shaping.h new file mode 100755 index 0000000..5eb7c6f --- /dev/null +++ b/frameworks/font/ui_text_shaping.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef GRAPHIC_LITE_TEXT_SHAPING_H +#define GRAPHIC_LITE_TEXT_SHAPING_H + +#include "graphic_config.h" +#if ENABLE_SHAPING +#include "font/ui_font_header.h" +#include + +enum ShapingScript { + SHAPING_SCRIPT_ARABIC, + SHAPING_SCRIPT_THAI, + SHAPING_SCRIPT_DEVANAGARI, + SHAPING_SCRIPT_HEBREW, + SHAPING_SCRIPT_MYANMAR, + SHAPING_SCRIPT_BENGALI, + SHAPING_SCRIPT_INVALID +}; + +namespace OHOS { +class UITextShaping { +public: + /** + * @brief Construct a new UITextShaping object + */ + UITextShaping(); + + /** + * @brief Destroy the UITextShaping object + */ + ~UITextShaping(); + + /** + * @brief Get the Instance object + * @return UITextShaping* the static instance + */ + static UITextShaping* GetInstance() + { + static UITextShaping instance; + return &instance; + } + + static bool IsSameTTFId(uint8_t fontId, uint32_t unicode); +}; // class UITextShaping +} // namespace OHOS +#endif // ENABLE_SHAPING +#endif // GRAPHIC_LITE_TEXT_SHAPING_H \ No newline at end of file diff --git a/frameworks/imgdecode/cache_manager.cpp b/frameworks/imgdecode/cache_manager.cpp new file mode 100755 index 0000000..e3465c8 --- /dev/null +++ b/frameworks/imgdecode/cache_manager.cpp @@ -0,0 +1,293 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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. + */ + +#include "imgdecode/cache_manager.h" +#include "graphic_log.h" +#include "hal_tick.h" +#include "securec.h" + +namespace OHOS { +const uint8_t* CacheEntry::GetImgData() const +{ + return dsc_.imgInfo.data; +} + +RetCode CacheEntry::ReadLine(const Point& start, int16_t len, uint8_t* buf) +{ + RetCode ret; + if (dsc_.decoder != nullptr) { + ret = dsc_.decoder->ReadLine(dsc_, start, len, buf); + } else { + ret = RetCode::FAIL; + } + + return ret; +} + +void CacheEntry::Clear() +{ + if (dsc_.decoder != nullptr) { + dsc_.decoder->Close(dsc_); + } + + dsc_.decoder = nullptr; + ClearSrc(); + dsc_.imgInfo.data = nullptr; + dsc_.fd = -1; + dsc_.srcType = IMG_SRC_UNKNOWN; + life_ = 0; +} + +void CacheEntry::ClearSrc() +{ + if (dsc_.srcType == IMG_SRC_FILE) { + UIFree(const_cast(dsc_.path)); + } + dsc_.path = nullptr; +} + +RetCode CacheEntry::SetSrc(const char* path) +{ + ClearSrc(); + if (dsc_.srcType == IMG_SRC_FILE) { + size_t strLen = strlen(path); + if (strLen > MAX_SRC_LENGTH) { + return RetCode::FAIL; + } + char* newStr = static_cast(UIMalloc(static_cast(strLen) + 1)); + if (newStr == nullptr) { + return RetCode::FAIL; + } + if (memcpy_s(newStr, strLen + 1, path, strLen) != EOK) { + UIFree(reinterpret_cast(newStr)); + newStr = nullptr; + return RetCode::FAIL; + } + newStr[strLen] = '\0'; + dsc_.path = newStr; + } else { + dsc_.path = path; + } + return RetCode::OK; +} + +RetCode CacheManager::Init(uint16_t size) +{ + if ((size == 0) || (size > MAX_CACHE_ENTRY_NUM)) { + return RetCode::FAIL; + } + Reset(); + if (entryArr_ != nullptr) { + UIFree(reinterpret_cast(entryArr_)); + } + + uint32_t tmpCacheSize = size * sizeof(CacheEntry); + entryArr_ = static_cast(UIMalloc(tmpCacheSize)); + if (entryArr_ == nullptr) { + size_ = 0; + return RetCode::FAIL; + } + + if (memset_s(entryArr_, tmpCacheSize, 0, tmpCacheSize) != EOK) { + UIFree(reinterpret_cast(entryArr_)); + entryArr_ = nullptr; + return RetCode::FAIL; + } + + size_ = size; + return RetCode::OK; +} + +RetCode CacheManager::Open(const char* path, const Style& style, CacheEntry& entry) +{ + if ((path == nullptr) || (GetSize() <= 0)) { + return RetCode::FAIL; + } + + AgingAll(); + uint16_t indexHitted = 0; + RetCode ret = GetIndex(path, indexHitted); + if (ret == RetCode::OK) { + ReadToCache(entryArr_[indexHitted]); + entry = entryArr_[indexHitted]; + return RetCode::OK; + } + + SelectEntryToReplace(indexHitted); + if (entryArr_[indexHitted].dsc_.path != nullptr) { + entryArr_[indexHitted].dsc_.decoder->Close(entryArr_[indexHitted].dsc_); + } + + uint32_t startTime = HALTick::GetInstance().GetTime(); + entryArr_[indexHitted].life_ = 0; + + ret = TryDecode(path, style, entryArr_[indexHitted]); + if (ret != RetCode::OK) { + return ret; + } + ReadToCache(entryArr_[indexHitted]); + entryArr_[indexHitted].life_ = HALTick::GetInstance().GetElapseTime(startTime); + entry = entryArr_[indexHitted]; + return RetCode::OK; +} + +RetCode CacheManager::Close(const char* path) +{ + if (path == nullptr) { + return RetCode::FAIL; + } + + for (uint16_t index = 0; index < GetSize(); index++) { + if (entryArr_[index].dsc_.srcType == IMG_SRC_FILE) { + if (entryArr_[index].dsc_.path == nullptr) { + continue; + } + if (strcmp(entryArr_[index].dsc_.path, path) == 0) { + entryArr_[index].dsc_.decoder->Close(entryArr_[index].dsc_); + Clear(entryArr_[index]); + break; + } + } else { + if (entryArr_[index].dsc_.path == path) { + entryArr_[index].dsc_.decoder->Close(entryArr_[index].dsc_); + Clear(entryArr_[index]); + break; + } + } + } + + return RetCode::OK; +} + +bool CacheManager::GetImageHeader(const char* path, ImageHeader& header) +{ + CacheEntry entry; + Style useless; + RetCode ret = Open(path, useless, entry); + if (ret != RetCode::OK) { + GRAPHIC_LOGW("CacheManager::GetImageHeader Image get info found unknown src type\n"); + return false; + } + + header = entry.GetImgHeader(); + return true; +} + +RetCode CacheManager::Reset() +{ + if (entryArr_ == nullptr) { + return RetCode::OK; + } + + for (uint16_t index = 0; index < GetSize(); index++) { + if (entryArr_[index].dsc_.path != nullptr) { + entryArr_[index].dsc_.decoder->Close(entryArr_[index].dsc_); + Clear(entryArr_[index]); + } + } + + return RetCode::OK; +} + +RetCode CacheManager::ReadToCache(CacheEntry& entry) +{ + return entry.dsc_.decoder->ReadToCache(entry.dsc_); +} + +void CacheManager::Clear(CacheEntry& entry) +{ + entry.Clear(); +} + +void CacheManager::AgingAll(int32_t time) +{ + for (uint16_t index = 0; index < GetSize(); index++) { + if (entryArr_[index].life_ > INT32_MIN + AGING_INTERVAL) { + entryArr_[index].life_ -= time; + } + } +} + +RetCode CacheManager::GetIndex(const char* path, uint16_t& hittedIndex) +{ + for (uint16_t index = 0; index < GetSize(); index++) { + if (entryArr_[index].dsc_.srcType == IMG_SRC_FILE) { + if ((entryArr_[index].dsc_.path != nullptr) && !strcmp(path, entryArr_[index].dsc_.path)) { + entryArr_[index].life_ += entryArr_[index].dsc_.timeToOpen * LIFE_GAIN_INTERVAL; + if (entryArr_[index].life_ > LIFE_LIMIT) { + entryArr_[index].life_ = LIFE_LIMIT; + } + hittedIndex = index; + return RetCode::OK; + } + } else { + ImageInfo* imgDsc = reinterpret_cast(const_cast(path)); + if ((entryArr_[index].dsc_.path == path) && (entryArr_[index].dsc_.imgInfo.data == imgDsc->data)) { + entryArr_[index].life_ += entryArr_[index].dsc_.timeToOpen * LIFE_GAIN_INTERVAL; + if (entryArr_[index].life_ > LIFE_LIMIT) { + entryArr_[index].life_ = LIFE_LIMIT; + } + hittedIndex = index; + return RetCode::OK; + } + } + } + + return RetCode::FAIL; +} + +RetCode CacheManager::SelectEntryToReplace(uint16_t& selectedIndex) +{ + selectedIndex = 0; + for (uint16_t index = 0; index < GetSize(); index++) { + if (entryArr_[index].life_ < entryArr_[selectedIndex].life_) { + selectedIndex = index; + } + } + + return RetCode::OK; +} + +RetCode CacheManager::TryDecode(const char* path, const Style& style, CacheEntry& entry) +{ + FileImgDecoder* decoder = &(FileImgDecoder::GetInstance()); + if (decoder == nullptr) { + Clear(entry); + return RetCode::FAIL; + } + + entry.dsc_.srcType = IMG_SRC_FILE; + RetCode ret = entry.SetSrc(path); + if (ret != RetCode::OK) { + Clear(entry); + return ret; + } + entry.dsc_.decoder = decoder; + + ret = entry.dsc_.decoder->GetHeader(entry.dsc_); + if (ret != RetCode::OK) { + Clear(entry); + return ret; + } + + ret = entry.dsc_.decoder->Open(entry.dsc_); + if (ret != RetCode::OK) { + Clear(entry); + return ret; + } + + return ret; +} +} // namespace OHOS diff --git a/frameworks/imgdecode/cache_manager.h b/frameworks/imgdecode/cache_manager.h new file mode 100755 index 0000000..a7258f3 --- /dev/null +++ b/frameworks/imgdecode/cache_manager.h @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef GRAPHIC_LITE_CACHE_MANAGER_H +#define GRAPHIC_LITE_CACHE_MANAGER_H + +#include "file_img_decoder.h" + +namespace OHOS { +class CacheEntry : public HeapBase { +public: + CacheEntry() : dsc_{0}, life_(0) {} + + ~CacheEntry() {} + + ImageSrcType GetImgSrcType() const + { + return dsc_.srcType; + } + + const uint8_t* GetImgData() const; + + ImageHeader GetImgHeader() const + { + return dsc_.imgInfo.header; + } + + ImageInfo GetImageInfo() const + { + return dsc_.imgInfo; + } + + RetCode ReadLine(const Point& start, int16_t bufSize, uint8_t* buf); + + bool InCache() const + { + return dsc_.inCache_; + } + +private: + static constexpr uint16_t MAX_SRC_LENGTH = 4096; + + friend class CacheManager; + + void Clear(); + void ClearSrc(); + RetCode SetSrc(const char* path); + + FileImgDecoder::ImgResDsc dsc_; + int32_t life_; +}; + +class CacheManager : public HeapBase { +public: + static CacheManager& GetInstance() + { + static CacheManager instance; + return instance; + } + + RetCode Init(uint16_t size); + + uint16_t GetSize() + { + return size_; + } + + RetCode Open(const char* path, const Style& style, CacheEntry& entry); + + RetCode Close(const char* path); + + RetCode Reset(); + + RetCode ReadToCache(CacheEntry& entry); + + bool GetImageHeader(const char* path, ImageHeader& header); + +private: + CacheManager() : size_(0), entryArr_(nullptr){} + + ~CacheManager() {} + + void Clear(CacheEntry& entry); + + void AgingAll(int32_t time = AGING_INTERVAL); + + RetCode GetIndex(const char* src, uint16_t& hittedIndex); + + RetCode SelectEntryToReplace(uint16_t& selectedIndex); + + RetCode TryDecode(const char* path, const Style& style, CacheEntry& entry); + + uint16_t size_; + CacheEntry* entryArr_; + static constexpr uint8_t AGING_INTERVAL = 1; + static constexpr uint8_t LIFE_GAIN_INTERVAL = 1; + static constexpr uint16_t LIFE_LIMIT = 1000; + static constexpr uint8_t MAX_CACHE_ENTRY_NUM = 32; +}; +} // namespace OHOS + +#endif \ No newline at end of file diff --git a/frameworks/imgdecode/file_img_decoder.cpp b/frameworks/imgdecode/file_img_decoder.cpp new file mode 100755 index 0000000..8267fc0 --- /dev/null +++ b/frameworks/imgdecode/file_img_decoder.cpp @@ -0,0 +1,159 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "file.h" +#include "imgdecode/file_img_decoder.h" +#include "imgdecode/image_load.h" +#include "mem_api.h" + +namespace OHOS { +RetCode FileImgDecoder::Open(ImgResDsc& dsc) +{ +#ifdef _WIN32 + int32_t fd = open(dsc.path, O_RDONLY | O_BINARY); +#else + int32_t fd = open(dsc.path, O_RDONLY); +#endif + if (fd == -1) { + return RetCode::FAIL; + } + dsc.fd = fd; + + dsc.imgInfo.data = nullptr; + dsc.inCache_ = false; + uint8_t colorMode = dsc.imgInfo.header.colorMode; + if (IsImgValidMode(colorMode)) { + dsc.imgInfo.data = nullptr; + return RetCode::OK; + } else { + return RetCode::FAIL; + } +} + +RetCode FileImgDecoder::Close(ImgResDsc& dsc) +{ + if (dsc.imgInfo.data != nullptr) { + ImageCacheFree(dsc.imgInfo); + dsc.imgInfo.data = nullptr; + } + if (dsc.fd && (dsc.fd != -1)) { + close(dsc.fd); + dsc.fd = -1; + } + + return RetCode::OK; +} + +RetCode FileImgDecoder::GetHeader(ImgResDsc& dsc) +{ + int32_t fd; + int32_t readCount; +#ifdef _WIN32 + fd = open(dsc.path, O_BINARY); +#else + fd = open(dsc.path, O_RDONLY); +#endif + if (fd == -1) { + return RetCode::FAIL; + } + + dsc.fd = fd; + readCount = read(fd, &dsc.imgInfo.header, sizeof(ImageHeader)); + close(fd); + dsc.fd = -1; + if (readCount != sizeof(ImageHeader)) { + dsc.imgInfo.header.width = 0; + dsc.imgInfo.header.height = 0; + dsc.imgInfo.header.colorMode = UNKNOW; + return RetCode::FAIL; + } + + return RetCode::OK; +} + +RetCode FileImgDecoder::ReadLine(ImgResDsc& dsc, const Point& start, int16_t len, uint8_t* buf) +{ + if (IsImgValidMode(dsc.imgInfo.header.colorMode)) { + return ReadLineTrueColor(dsc, start, len, buf); + } + return RetCode::FAIL; +} + +RetCode FileImgDecoder::ReadToCache(ImgResDsc& dsc) +{ + struct stat info; + if (!dsc.inCache_) { + lseek(dsc.fd, 0, SEEK_SET); + int32_t readCount = read(dsc.fd, &dsc.imgInfo.header, sizeof(ImageHeader)); + if (readCount != sizeof(ImageHeader)) { + return RetCode::FAIL; + } + + int32_t ret = fstat(dsc.fd, &info); + if (ret != 0) { + return RetCode::FAIL; + } + uint32_t pxCount = info.st_size - readCount; + if (dsc.imgInfo.data != nullptr) { + ImageCacheFree(dsc.imgInfo); + } + + bool readSuccess = false; + if (dsc.imgInfo.header.compressMode != COMPRESS_MODE_NONE) { + readSuccess = ImageLoad::GetImageInfo(dsc.fd, pxCount, dsc.imgInfo); + } else { + dsc.imgInfo.dataSize = pxCount; + dsc.imgInfo.data = reinterpret_cast(ImageCacheMalloc(dsc.imgInfo)); + if (dsc.imgInfo.data == nullptr) { + return RetCode::OK; + } + uint8_t* tmp = const_cast(dsc.imgInfo.data); + readSuccess = (static_cast(pxCount) == read(dsc.fd, reinterpret_cast(tmp), pxCount)); + } + if (!readSuccess) { + ImageCacheFree(dsc.imgInfo); + dsc.imgInfo.dataSize = 0; + close(dsc.fd); + dsc.fd = -1; + return RetCode::OK; + } + dsc.inCache_ = true; + close(dsc.fd); + dsc.fd = -1; + } + + return RetCode::OK; +} + +RetCode FileImgDecoder::ReadLineTrueColor(ImgResDsc& dsc, const Point& start, int16_t len, uint8_t* buf) +{ + uint8_t pxSizeInBit = DrawUtils::GetPxSizeByImageInfo(dsc.imgInfo); + off_t res; + + uint32_t pos = ((start.y * dsc.imgInfo.header.width + start.x) * pxSizeInBit) >> BYTE_TO_BIT_SHIFT; + pos += sizeof(ImageHeader); /* Skip the header */ + res = lseek(dsc.fd, pos, SEEK_SET); + if (res == -1) { + return RetCode::FAIL; + } + uint32_t btr = len * (pxSizeInBit >> BYTE_TO_BIT_SHIFT); + int32_t br = read(dsc.fd, buf, btr); + if ((br == -1) || (btr != static_cast(br))) { + return RetCode::FAIL; + } + + return RetCode::OK; +} +} // namespace OHOS diff --git a/frameworks/imgdecode/file_img_decoder.h b/frameworks/imgdecode/file_img_decoder.h new file mode 100755 index 0000000..0e25f93 --- /dev/null +++ b/frameworks/imgdecode/file_img_decoder.h @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef GRAPHIC_LITE_FILE_IMG_DECODER_H +#define GRAPHIC_LITE_FILE_IMG_DECODER_H + +#include "draw/draw_image.h" +#include "draw/draw_utils.h" + +namespace OHOS { +constexpr uint8_t BYTE_TO_BIT_SHIFT = 3; +constexpr uint8_t ONE_BIT_LEN_IN_BIT = 1; +constexpr uint8_t TWO_BIT_LEN_IN_BIT = 2; +constexpr uint8_t FOUR_BIT_LEN_IN_BIT = 4; +constexpr uint8_t BYTE_LEN_IN_BIT = 8; + +enum class RetCode { + OK, + FAIL, +}; + +class FileImgDecoder : public HeapBase { +public: + static FileImgDecoder& GetInstance() + { + static FileImgDecoder instance; + return instance; + } + + struct ImgResDsc { + FileImgDecoder* decoder; + const char* path; + ImageInfo imgInfo; + uint32_t timeToOpen; + int32_t fd; + ImageSrcType srcType; + bool inCache_; + }; + + RetCode Open(ImgResDsc& dsc); + + RetCode Close(ImgResDsc& dsc); + + RetCode GetHeader(ImgResDsc& dsc); + + RetCode ReadLine(ImgResDsc& dsc, const Point& start, int16_t len, uint8_t* buf); + + RetCode ReadToCache(ImgResDsc& dsc); + +private: + FileImgDecoder() {}; + ~FileImgDecoder() {}; + + bool IsImgValidMode(uint8_t colorMode) + { + if ((colorMode == RGB565) || (colorMode == RGB888) || (colorMode == ARGB8888)) { + return true; + } else { + return false; + } + } + RetCode ReadLineTrueColor(ImgResDsc& dsc, const Point& start, int16_t len, uint8_t* buf); + + FileImgDecoder(const FileImgDecoder&) = delete; + FileImgDecoder& operator=(const FileImgDecoder&) = delete; + FileImgDecoder(FileImgDecoder&&) = delete; + FileImgDecoder& operator=(FileImgDecoder&&) = delete; +}; +} +#endif \ No newline at end of file diff --git a/frameworks/imgdecode/image_load.cpp b/frameworks/imgdecode/image_load.cpp new file mode 100755 index 0000000..925e301 --- /dev/null +++ b/frameworks/imgdecode/image_load.cpp @@ -0,0 +1,206 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "imgdecode/image_load.h" +#include "file.h" +#include "graphic_log.h" +#include "mem_api.h" + +namespace { +const uint8_t BITMAP_ZIP_LEN = 3; +const uint8_t BITMAP_MID_BIT = 1; +const uint8_t BITMAP_LOW_BIT = 2; +const uint32_t BITMAP_ZIP24_FLAG = 0x456789; +const uint32_t BITMAP_ZIP_FLAG = 0x23456789; +const uint32_t BITMAP_ALPHA_MASK = 0xFF000000; +const uint32_t BITMAP_MAXCON_PIXNUM = 0xCB100; +const uint32_t MOVE_HIGH = 16; +const uint32_t MOVE_LOW = 8; +} // namespace + +namespace OHOS { +bool ImageLoad::CreateImage(ImageInfo& imageInfo) +{ + uint32_t bytePerPixel = 4; + ImageHeader& imageHeader = imageInfo.header; + + switch (imageHeader.colorMode) { + case ARGB8888: + bytePerPixel = 4; // 4 bytes per pixel + break; + case RGB888: + bytePerPixel = 3; // 3 bytes per pixel + break; + case RGB565: + bytePerPixel = 2; // 2 bytes per pixel + break; + default: + GRAPHIC_LOGE("CreateImage invalid colorMode."); + return false; + } + + imageInfo.dataSize = imageHeader.width * imageHeader.height * bytePerPixel; + imageInfo.data = static_cast(ImageCacheMalloc(imageInfo)); + if (imageInfo.data == nullptr) { + GRAPHIC_LOGE("ImageCacheMalloc error."); + return false; + } + + return true; +} + +bool ImageLoad::UncompressImageInZip(ImageInfo& imageInfo, uint8_t* buffer, uint32_t size) +{ + if (!CreateImage(imageInfo)) { + GRAPHIC_LOGE("Create image error."); + return false; + } + + if (imageInfo.header.colorMode == RGB888) { + return Unzip24Image(buffer, size, imageInfo); + } else { + return UnzipImage(buffer, size, imageInfo); + } +} + +bool ImageLoad::UnzipImage(uint8_t* imageBuffer, uint32_t size, ImageInfo& imageInfo) +{ + uint32_t value = 0; + uint32_t count = 0; + + if ((imageBuffer == nullptr) || (size == 0)) { + GRAPHIC_LOGE("imageHeader is null."); + return false; + } + + uint32_t* source = reinterpret_cast(imageBuffer); + uint32_t* sourceEnd = reinterpret_cast(imageBuffer + size); + uint32_t* dest = nullptr; + uint32_t* destEnd = nullptr; + + dest = reinterpret_cast(const_cast(imageInfo.data)); + destEnd = reinterpret_cast(const_cast(imageInfo.data) + imageInfo.dataSize); + + while ((source < sourceEnd) && (dest < destEnd)) { + if (*source != BITMAP_ZIP_FLAG) { + *dest++ = *source++; + } else { + source++; + value = *source++; + count = *source++; + if (destEnd < count + dest) { + break; + } + + while (count--) { + *dest++ = value; + } + } + } + + if (dest == destEnd) { + return true; + } + ImageCacheFree(imageInfo); + return false; +} + +bool ImageLoad::Unzip24Image(uint8_t* imageBuffer, uint32_t size, ImageInfo& imageInfo) +{ + if ((imageBuffer == nullptr) || (size == 0)) { + GRAPHIC_LOGE("imageHeader is null."); + return false; + } + + uint8_t* source = reinterpret_cast(imageBuffer); + uint8_t* sourceEnd = reinterpret_cast(imageBuffer + size); + uint32_t* dest = reinterpret_cast(const_cast(imageInfo.data)); + uint32_t* destEnd = reinterpret_cast(const_cast(imageInfo.data) + imageInfo.dataSize); + while ((source < sourceEnd) && (dest < destEnd)) { + uint32_t count = 0; + uint32_t value = 0; + + // Little endian + value = ((*source)) + (*(source + BITMAP_MID_BIT) << MOVE_LOW) + (*(source + BITMAP_LOW_BIT) << MOVE_HIGH); + source = source + BITMAP_ZIP_LEN; + if (value != BITMAP_ZIP24_FLAG) { + *dest = value | BITMAP_ALPHA_MASK; + dest++; + } else { + value = 0; + value = ((*source)) + (*(source + BITMAP_MID_BIT) << MOVE_LOW) + (*(source + BITMAP_LOW_BIT) << MOVE_HIGH); + source = source + BITMAP_ZIP_LEN; + + count = 0; + count = ((*source)) + (*(source + BITMAP_MID_BIT) << MOVE_LOW) + (*(source + BITMAP_LOW_BIT) << MOVE_HIGH); + source = source + BITMAP_ZIP_LEN; + + if (count > BITMAP_MAXCON_PIXNUM) { + *dest = BITMAP_ZIP24_FLAG | BITMAP_ALPHA_MASK; + dest++; + *dest = value | BITMAP_ALPHA_MASK; + dest++; + *dest = count | BITMAP_ALPHA_MASK; + dest++; + continue; + } + if (static_cast(destEnd - dest) < static_cast(count)) { + break; + } + while (count--) { + *dest = value | BITMAP_ALPHA_MASK; + dest++; + } + } + } + + if (dest == destEnd) { + return true; + } + ImageCacheFree(imageInfo); + return false; +} + +bool ImageLoad::UnZip2ImageInfo(ImageInfo& imageInfo, uint8_t* buffer, uint32_t size) +{ + switch (imageInfo.header.compressMode) { + case COMPRESS_MODE__ZIP_ALG: + return UncompressImageInZip(imageInfo, buffer, size); + default: + return false; + } +} + +bool ImageLoad::GetImageInfo(int32_t fd, uint32_t size, ImageInfo& imageInfo) +{ + if (size == 0) { + return false; + } + + uint8_t* buffer = reinterpret_cast(UIMalloc(size)); + if (buffer == nullptr) { + return false; + } + + if (read(fd, buffer, size) != static_cast(size)) { + UIFree(buffer); + GRAPHIC_LOGE("SeekImageFile error."); + return false; + } + bool ret = UnZip2ImageInfo(imageInfo, buffer, size); + UIFree(buffer); + return ret; +} +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/imgdecode/image_load.h b/frameworks/imgdecode/image_load.h new file mode 100755 index 0000000..b4ed0a3 --- /dev/null +++ b/frameworks/imgdecode/image_load.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef GRAPHIC_LITE_IMAGE_LOAD_H +#define GRAPHIC_LITE_IMAGE_LOAD_H + +#include "image_info.h" + +namespace OHOS { +enum CompressMode : uint8_t { + COMPRESS_MODE_NONE = 0, + COMPRESS_MODE__ZIP_ALG, + COMPRESS_MODE_BITMAP_ALG, + COMPRESS_MODE_BLOCK_ALG, +}; + +class ImageLoad { +public: + static bool GetImageInfo(int32_t fd, uint32_t size, ImageInfo& imageInfo); + +private: + ImageLoad() = delete; + ~ImageLoad() = delete; + + static bool UnZip2ImageInfo(ImageInfo& imageInfo, uint8_t* buffer, uint32_t size); + static bool UncompressImageInZip(ImageInfo& imageInfo, uint8_t* buffer, uint32_t size); + static bool CreateImage(ImageInfo& imageInfo); + static bool Unzip24Image(uint8_t* imageBuffer, uint32_t size, ImageInfo& imageInfo); + static bool UnzipImage(uint8_t* imageBuffer, uint32_t size, ImageInfo& imageInfo); +}; +} // namespace OHOS +#endif // GRAPHIC_LITE_IMAGE_LOAD_H \ No newline at end of file diff --git a/frameworks/layout/flex_layout.cpp b/frameworks/layout/flex_layout.cpp new file mode 100755 index 0000000..98205a5 --- /dev/null +++ b/frameworks/layout/flex_layout.cpp @@ -0,0 +1,502 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "layout/flex_layout.h" + +namespace OHOS { +void FlexLayout::LayoutChildren(bool needInvalidate) +{ + if (childrenHead_ == nullptr) { + return; + } + + if ((direction_ == LAYOUT_HOR) || (direction_ == LAYOUT_HOR_R)) { + LayoutHorizontal(); + } else { + LayoutVertical(); + } + if (needInvalidate) { + Invalidate(); + } +} + +void FlexLayout::GetStartPos(const int16_t& length, + int16_t& pos, + int16_t& interval, + int16_t count, + uint16_t* validLengths, + uint16_t* childsNum) +{ + if (!validLengths || !childsNum) { + return; + } + pos = 0; + interval = 0; + + if (majorAlign_ == ALIGN_START) { + pos = 0; + } else if (majorAlign_ == ALIGN_END) { + pos = length - validLengths[count]; + /* if total length of children is too long or only one child, layout them centerly no matter what key word set. + */ + } else if ((majorAlign_ == ALIGN_CENTER) || (validLengths[count] >= length) || (childsNum[count] == 1)) { + pos = (length - validLengths[count]) / 2; // 2: half + } else if (majorAlign_ == ALIGN_AROUND) { + if (childsNum[count] == 0) { + return; + } + interval = (length - validLengths[count]) / childsNum[count]; + pos = interval / 2; // 2: half + } else if (majorAlign_ == ALIGN_EVENLY) { + interval = (length - validLengths[count]) / (childsNum[count] + 1); + pos = interval; + } else { + if (childsNum[count] == 1) { + return; + } + interval = (length - validLengths[count]) / (childsNum[count] - 1); + pos = 0; + } +} + +void FlexLayout::GetNoWrapStartPos(const int16_t& length, int16_t& majorPos, int16_t& interval) +{ + uint16_t childrenNum = 0; + uint16_t totalValidLength = 0; + + CalValidLength(totalValidLength, childrenNum); + GetStartPos(length, majorPos, interval, 0, &totalValidLength, &childrenNum); +} + +void FlexLayout::GetRowStartPos(int16_t& pos, + int16_t& interval, + int16_t count, + uint16_t* rowsWidth, + uint16_t* rowsChildNum) +{ + GetStartPos(GetWidth(), pos, interval, count, rowsWidth, rowsChildNum); +} + +void FlexLayout::GetColumnStartPos(int16_t& pos, + int16_t& interval, + int16_t count, + uint16_t* columnsHeight, + uint16_t* columnsChildNum) +{ + GetStartPos(GetHeight(), pos, interval, count, columnsHeight, columnsChildNum); +} + +void FlexLayout::CalValidLength(uint16_t& totalValidLength, uint16_t& allChildNum) +{ + UIView* child = childrenHead_; + int16_t left; + int16_t right; + int16_t top; + int16_t bottom; + + /* calculate valid length of all children views */ + while (child != nullptr) { + if (child->IsVisible()) { + if ((direction_ == LAYOUT_HOR) || (direction_ == LAYOUT_HOR_R)) { + left = child->GetStyle(STYLE_MARGIN_LEFT); + right = child->GetStyle(STYLE_MARGIN_RIGHT); + totalValidLength += (child->GetRelativeRect().GetWidth() + left + right); + } else { + top = child->GetStyle(STYLE_MARGIN_TOP); + bottom = child->GetStyle(STYLE_MARGIN_BOTTOM); + totalValidLength += (child->GetRelativeRect().GetHeight() + top + bottom); + } + allChildNum++; + } + child = child->GetNextSibling(); + } +} + +void FlexLayout::CalRowCount() +{ + UIView* child = childrenHead_; + int16_t pos = 0; + int16_t left; + int16_t right; + + rowCount_ = 1; + while (child != nullptr) { + if (child->IsVisible()) { + left = child->GetStyle(STYLE_MARGIN_LEFT); + right = child->GetStyle(STYLE_MARGIN_RIGHT); + pos += left; + if ((pos + child->GetRelativeRect().GetWidth() + right) > GetWidth()) { + pos = left; + rowCount_++; + } + pos += child->GetRelativeRect().GetWidth() + right; + } + child = child->GetNextSibling(); + } +} + +void FlexLayout::GetRowMaxHeight(uint16_t size, uint16_t* maxRosHegiht) +{ + UIView* child = childrenHead_; + int16_t pos = 0; + int16_t left; + int16_t right; + int16_t top; + int16_t bottom; + uint16_t i = 0; + uint16_t height = 0; + + if ((maxRosHegiht == nullptr) || (size > rowCount_)) { + return; + } + + while (child != nullptr) { + if (child->IsVisible()) { + left = child->GetStyle(STYLE_MARGIN_LEFT); + right = child->GetStyle(STYLE_MARGIN_RIGHT); + top = child->GetStyle(STYLE_MARGIN_TOP); + bottom = child->GetStyle(STYLE_MARGIN_BOTTOM); + pos += left; + if ((pos + child->GetRelativeRect().GetWidth() + right) > GetWidth()) { + pos = left; + maxRosHegiht[i] = height; + height = 0; + i++; + } + height = MATH_MAX(height, child->GetRelativeRect().GetHeight() + top + bottom); + maxRosHegiht[i] = height; + pos += child->GetRelativeRect().GetWidth() + right; + } + child = child->GetNextSibling(); + } +} + +void FlexLayout::GetRowsWidth(uint16_t rowNum, uint16_t* rowsWidth, uint16_t* rowsChildNum) +{ + UIView* child = childrenHead_; + int16_t pos = 0; + int16_t left; + int16_t right; + uint16_t rowChildNum = 0; + uint16_t rowCount = 0; + uint16_t width = 0; + + if ((rowsWidth == nullptr) || (rowsChildNum == nullptr) || (rowNum > rowCount_)) { + return; + } + + while (child != nullptr) { + if (child->IsVisible()) { + left = child->GetStyle(STYLE_MARGIN_LEFT); + right = child->GetStyle(STYLE_MARGIN_RIGHT); + pos += left; + if ((pos + child->GetRelativeRect().GetWidth() + right) > GetWidth()) { + pos = left; + rowsWidth[rowCount] = width; + width = 0; + rowsChildNum[rowCount] = rowChildNum; + rowChildNum = 0; + rowCount++; + } + width += child->GetRelativeRect().GetWidth() + right + left; + rowsWidth[rowCount] = width; + rowChildNum++; + rowsChildNum[rowCount] = rowChildNum; + pos += child->GetRelativeRect().GetWidth() + right; + } + child = child->GetNextSibling(); + } +} + +void FlexLayout::GetCrossAxisPosY(int16_t& posY, uint16_t& count, uint16_t* rowsMaxHeight, UIView* child) +{ + if ((rowsMaxHeight == nullptr) || (child == nullptr)) { + return; + } + + uint16_t i = 0; + uint16_t offset = 0; + int16_t top = child->GetStyle(STYLE_MARGIN_TOP); + int16_t bottom = child->GetStyle(STYLE_MARGIN_BOTTOM); + + if (secondaryAlign_ == ALIGN_START) { + for (i = 0; i < count; i++) { + offset += rowsMaxHeight[i]; + } + posY = top + offset; + } else if (secondaryAlign_ == ALIGN_END) { + for (i = rowCount_ - 1; i > count; i--) { + offset += rowsMaxHeight[i]; + } + posY = GetHeight() - child->GetRelativeRect().GetHeight() - bottom - offset; + } else { + for (i = 0; i < rowCount_; i++) { + offset += rowsMaxHeight[i]; + } + offset = (rowsMaxHeight[0] - offset) / 2; // 2: half + for (i = 1; i <= count; i++) { + offset += (rowsMaxHeight[i - 1] + rowsMaxHeight[i]) / 2; // 2: half + } + posY = (GetHeight() - child->GetRelativeRect().GetHeight() - top - bottom) / 2 + top + offset; // 2: half + } +} + +void FlexLayout::LayoutHorizontal() +{ + UIView* child = childrenHead_; + int16_t interval = 0; + int16_t posX = 0; + int16_t posY = 0; + uint16_t count = 0; + uint16_t widthsBuf[MAX_COUNT_DEFAULT] = {0}; + uint16_t maxHeightsBuf[MAX_COUNT_DEFAULT] = {0}; + uint16_t childsNumBuf[MAX_COUNT_DEFAULT] = {0}; + uint16_t* rowsWidth = widthsBuf; + uint16_t* rowsMaxHeight = maxHeightsBuf; + uint16_t* rowsChildNum = childsNumBuf; + bool allocFlag = false; + + if (wrap_ == WRAP) { + CalRowCount(); + if (rowCount_ > MAX_COUNT_DEFAULT) { + rowsWidth = new uint16_t[rowCount_](); + rowsMaxHeight = new uint16_t[rowCount_](); + rowsChildNum = new uint16_t[rowCount_](); + allocFlag = true; + } + GetRowMaxHeight(rowCount_, rowsMaxHeight); + GetRowsWidth(rowCount_, rowsWidth, rowsChildNum); + GetRowStartPos(posX, interval, count, rowsWidth, rowsChildNum); + } else { + GetNoWrapStartPos(GetWidth(), posX, interval); + } + + while (child != nullptr) { + if (child->IsVisible()) { + child->ReMeasure(); + int16_t left = child->GetStyle(STYLE_MARGIN_LEFT); + int16_t right = child->GetStyle(STYLE_MARGIN_RIGHT); + posX += left; + if (((posX + child->GetRelativeRect().GetWidth() + right) > GetWidth()) && (wrap_ == WRAP)) { + GetRowStartPos(posX, interval, ++count, rowsWidth, rowsChildNum); + posX += left; + } + + GetCrossAxisPosY(posY, count, rowsMaxHeight, child); + if (direction_ == LAYOUT_HOR_R) { + child->SetPosition(GetWidth() - (posX - left) - child->GetRelativeRect().GetWidth() - right, posY); + } else { + child->SetPosition(posX, posY); + } + posX += child->GetRelativeRect().GetWidth() + right + interval; + child->LayoutChildren(); + } + child = child->GetNextSibling(); + } + + if (allocFlag) { + delete[] rowsWidth; + delete[] rowsMaxHeight; + delete[] rowsChildNum; + } +} + +void FlexLayout::CalColumnCount() +{ + UIView* child = childrenHead_; + int16_t pos = 0; + int16_t top; + int16_t bottom; + + columnCount_ = 1; + while (child != nullptr) { + if (child->IsVisible()) { + top = child->GetStyle(STYLE_MARGIN_TOP); + bottom = child->GetStyle(STYLE_MARGIN_BOTTOM); + pos += top; + if ((pos + child->GetRelativeRect().GetHeight() + bottom) > GetHeight()) { + pos = top; + columnCount_++; + } + pos += child->GetRelativeRect().GetHeight() + bottom; + } + child = child->GetNextSibling(); + } +} + +void FlexLayout::GetColumnMaxWidth(uint16_t size, uint16_t* maxColumnsWidth) +{ + UIView* child = childrenHead_; + int16_t pos = 0; + int16_t left; + int16_t right; + int16_t bottom; + uint16_t i = 0; + uint16_t width = 0; + + if ((maxColumnsWidth == nullptr) || (size > columnCount_)) { + return; + } + + while (child != nullptr) { + if (child->IsVisible()) { + left = child->GetStyle(STYLE_MARGIN_LEFT); + right = child->GetStyle(STYLE_MARGIN_RIGHT); + bottom = child->GetStyle(STYLE_MARGIN_BOTTOM); + pos += left; + if ((pos + child->GetRelativeRect().GetHeight() + bottom) > GetHeight()) { + pos = left; + maxColumnsWidth[i] = width; + width = 0; + i++; + } + width = MATH_MAX(width, child->GetRelativeRect().GetWidth() + left + right); + maxColumnsWidth[i] = width; + pos += child->GetRelativeRect().GetHeight() + bottom; + } + child = child->GetNextSibling(); + } +} + +void FlexLayout::GetColumnsHeight(uint16_t columnNum, uint16_t* columnsHeight, uint16_t* columnsChildNum) +{ + UIView* child = childrenHead_; + int16_t pos = 0; + int16_t top; + int16_t bottom; + uint16_t columnChildNum = 0; + uint16_t columnCount = 0; + uint16_t height = 0; + + if ((columnsHeight == nullptr) || (columnsChildNum == nullptr) || (columnNum > columnCount_)) { + return; + } + + while (child != nullptr) { + if (child->IsVisible()) { + top = child->GetStyle(STYLE_MARGIN_TOP); + bottom = child->GetStyle(STYLE_MARGIN_BOTTOM); + pos += top; + if ((pos + child->GetRelativeRect().GetHeight() + bottom) > GetHeight()) { + pos = top; + columnsHeight[columnCount] = height; + height = 0; + columnsChildNum[columnCount] = columnChildNum; + columnChildNum = 0; + columnCount++; + } + height += child->GetRelativeRect().GetHeight() + top + bottom; + columnsHeight[columnCount] = height; + columnChildNum++; + columnsChildNum[columnCount] = columnChildNum; + pos += child->GetRelativeRect().GetHeight() + bottom; + } + child = child->GetNextSibling(); + } +} + +void FlexLayout::GetCrossAxisPosX(int16_t& posX, uint16_t& count, uint16_t* columnsMaxWidth, UIView* child) +{ + if ((columnsMaxWidth == nullptr) || (child == nullptr)) { + return; + } + + uint16_t i = 0; + uint16_t offset = 0; + int16_t left = child->GetStyle(STYLE_MARGIN_LEFT); + int16_t right = child->GetStyle(STYLE_MARGIN_RIGHT); + + if (secondaryAlign_ == ALIGN_START) { + for (i = 0; i < count; i++) { + offset += columnsMaxWidth[i]; + } + posX = left + offset; + } else if (secondaryAlign_ == ALIGN_END) { + for (i = columnCount_ - 1; i > count; i--) { + offset += columnsMaxWidth[i]; + } + posX = GetWidth() - child->GetRelativeRect().GetWidth() - right - offset; + } else { + for (i = 0; i < columnCount_; i++) { + offset += columnsMaxWidth[i]; + } + offset = (columnsMaxWidth[0] - offset) / 2; // 2: half + for (i = 1; i <= count; i++) { + offset += (columnsMaxWidth[i - 1] + columnsMaxWidth[i]) / 2; // 2: half + } + posX = (GetWidth() - child->GetRelativeRect().GetWidth() - left - right) / 2 + left + offset; // 2: half + } +} + +void FlexLayout::LayoutVertical() +{ + UIView* child = childrenHead_; + int16_t interval = 0; + int16_t posX = 0; + int16_t posY = 0; + uint16_t count = 0; + uint16_t heightsBuf[MAX_COUNT_DEFAULT] = {0}; + uint16_t maxWidthsBuf[MAX_COUNT_DEFAULT] = {0}; + uint16_t childsNumBuf[MAX_COUNT_DEFAULT] = {0}; + uint16_t* columnsHeight = heightsBuf; + uint16_t* columnsMaxWidth = maxWidthsBuf; + uint16_t* columnsChildNum = childsNumBuf; + bool allocFlag = false; + + if (wrap_ == WRAP) { + CalColumnCount(); + if (columnCount_ > MAX_COUNT_DEFAULT) { + columnsHeight = new uint16_t[columnCount_](); + columnsMaxWidth = new uint16_t[columnCount_](); + columnsChildNum = new uint16_t[columnCount_](); + allocFlag = true; + } + GetColumnMaxWidth(columnCount_, columnsMaxWidth); + GetColumnsHeight(columnCount_, columnsHeight, columnsChildNum); + GetColumnStartPos(posY, interval, count, columnsHeight, columnsChildNum); + } else { + GetNoWrapStartPos(GetHeight(), posY, interval); + } + + while (child != nullptr) { + if (child->IsVisible()) { + child->ReMeasure(); + int16_t top = child->GetStyle(STYLE_MARGIN_TOP); + int16_t bottom = child->GetStyle(STYLE_MARGIN_BOTTOM); + posY += top; + if (((posY + child->GetRelativeRect().GetHeight() + bottom) > GetHeight()) && (wrap_ == WRAP)) { + GetColumnStartPos(posY, interval, ++count, columnsHeight, columnsChildNum); + posY += top; + } + + GetCrossAxisPosX(posX, count, columnsMaxWidth, child); + if (direction_ == LAYOUT_VER_R) { + child->SetPosition(posX, GetHeight() - (posY - top) - child->GetRelativeRect().GetHeight() - bottom); + } else { + child->SetPosition(posX, posY); + } + posY += child->GetRelativeRect().GetHeight() + bottom + interval; + child->LayoutChildren(); + } + child = child->GetNextSibling(); + } + + if (allocFlag) { + delete[] columnsHeight; + delete[] columnsMaxWidth; + delete[] columnsChildNum; + } +} +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/layout/grid_layout.cpp b/frameworks/layout/grid_layout.cpp new file mode 100755 index 0000000..415102a --- /dev/null +++ b/frameworks/layout/grid_layout.cpp @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "layout/grid_layout.h" + +namespace OHOS { +void GridLayout::LayoutChildren(bool needInvalidate) +{ + if (childrenHead_ == nullptr) { + return; + } + UIView* child = childrenHead_; + if ((rows_ == 0) || (cols_ == 0)) { + RemoveAll(); + return; + } + int16_t childrenNum = 0; + while (child != nullptr) { + childrenNum++; + child = child->GetNextSibling(); + } + if (rows_ * cols_ < childrenNum) { + RemoveAll(); + return; + } + + if (direction_ == LAYOUT_HOR) { + LayoutHorizontal(); + } else { + LayoutVertical(); + } + if (needInvalidate) { + Invalidate(); + } +} + +void GridLayout::LayoutHorizontal() +{ + UIView* child = childrenHead_; + int16_t left; + int16_t right; + int16_t top; + int16_t bottom; + int16_t layoutWidth = GetWidth() / cols_; + int16_t layoutHeight = GetHeight() / rows_; + int16_t posX; + int16_t posY; + for (int16_t i = 0; i < rows_; i++) { + posY = i * layoutHeight; + for (int16_t j = 0; j < cols_; j++) { + if (child == nullptr) { + return; + } + posX = j * layoutWidth; + child->ReMeasure(); + left = child->GetStyle(STYLE_MARGIN_LEFT); + right = child->GetStyle(STYLE_MARGIN_RIGHT); + top = child->GetStyle(STYLE_MARGIN_TOP); + bottom = child->GetStyle(STYLE_MARGIN_BOTTOM); + // 2: half + int16_t actPosX = posX + (layoutWidth - child->GetRelativeRect().GetWidth() - left - right) / 2 + left; + // 2: half + int16_t actPosY = posY + (layoutHeight - child->GetRelativeRect().GetHeight() - top - bottom) / 2 + top; + child->SetPosition(actPosX, actPosY); + child->LayoutChildren(); + child->ResizeVisibleArea(posX, posY, layoutWidth, layoutHeight); + child = child->GetNextSibling(); + } + } +} + +void GridLayout::LayoutVertical() +{ + UIView* child = childrenHead_; + int16_t left; + int16_t right; + int16_t top; + int16_t bottom; + int16_t layoutWidth = GetWidth() / cols_; + int16_t layoutHeight = GetHeight() / rows_; + int16_t posX; + int16_t posY; + for (int16_t i = 0; i < cols_; i++) { + posX = i * layoutWidth; + for (int16_t j = 0; j < rows_; j++) { + if (child == nullptr) { + return; + } + posY = j * layoutHeight; + child->ReMeasure(); + left = child->GetStyle(STYLE_MARGIN_LEFT); + right = child->GetStyle(STYLE_MARGIN_RIGHT); + top = child->GetStyle(STYLE_MARGIN_TOP); + bottom = child->GetStyle(STYLE_MARGIN_BOTTOM); + // 2: half + int16_t actPosX = posX + (layoutWidth - child->GetRelativeRect().GetWidth() - left - right) / 2 + left; + // 2: half + int16_t actPosY = posY + (layoutHeight - child->GetRelativeRect().GetHeight() - top - bottom) / 2 + top; + child->SetPosition(actPosX, actPosY); + child->LayoutChildren(); + child->ResizeVisibleArea(posX, posY, layoutWidth, layoutHeight); + child = child->GetNextSibling(); + } + } +} +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/layout/list_layout.cpp b/frameworks/layout/list_layout.cpp new file mode 100755 index 0000000..5ca4c13 --- /dev/null +++ b/frameworks/layout/list_layout.cpp @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "layout/list_layout.h" + +namespace OHOS { +ListLayout::ListLayout(const uint8_t direction) : listDirection_(direction) +{ + SetLayoutDirect(direction); +} + +void ListLayout::SetDirection(uint8_t direction) +{ + listDirection_ = direction; + SetLayoutDirect(direction); + OnChildChanged(); +} + +void ListLayout::SetLayoutDirect(uint8_t direction) +{ + if (direction == VERTICAL) { + direction_ = LAYOUT_VER; + } else { + direction_ = LAYOUT_HOR; + } +} + +void ListLayout::OnChildChanged() +{ + LayoutChildren(true); + Rect rect = GetAllChildRelativeRect(); + if (listDirection_ == VERTICAL) { + SetHeight(rect.GetHeight() + rect.GetTop()); + } else { + SetWidth(rect.GetWidth() + rect.GetLeft()); + } +} +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/themes/theme.cpp b/frameworks/themes/theme.cpp new file mode 100755 index 0000000..4818ece --- /dev/null +++ b/frameworks/themes/theme.cpp @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "themes/theme.h" +#include "components/root_view.h" +#include "components/ui_view.h" + +namespace OHOS { +Theme::Theme() +{ + InitBasicStyle(); + InitButtonStyle(); + InitLabelStyle(); + InitPickerStyle(); + InitProgressStyle(); + InitSliderStyle(); +}; + +void Theme::InitBasicStyle() +{ + basicStyle_ = StyleDefault::GetDefaultStyle(); +} + +void Theme::InitButtonStyle() +{ + buttonStyle_.released = StyleDefault::GetButtonReleasedStyle(); + buttonStyle_.pressed = StyleDefault::GetButtonPressedStyle(); +} + +void Theme::InitLabelStyle() +{ + labelStyle_ = StyleDefault::GetLabelStyle(); +} + +void Theme::InitPickerStyle() +{ + pickerBackgroundStyle_ = StyleDefault::GetPickerBackgroundStyle(); + pickerHighlightStyle_ = StyleDefault::GetPickerHighlightStyle(); +} + +void Theme::InitProgressStyle() +{ + progressBackgroundStyle_ = StyleDefault::GetProgressBackgroundStyle(); + progressForegroundStyle_ = StyleDefault::GetProgressForegroundStyle(); +} + +void Theme::InitSliderStyle() +{ + sliderKnobStyle_ = StyleDefault::GetPickerBackgroundStyle(); +} +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/themes/theme_manager.cpp b/frameworks/themes/theme_manager.cpp new file mode 100755 index 0000000..b69879a --- /dev/null +++ b/frameworks/themes/theme_manager.cpp @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "themes/theme_manager.h" + +namespace OHOS { +void ThemeManager::SetCurrent(Theme* theme) +{ + if (theme_ != nullptr) { + delete theme_; + } + theme_ = theme; +} +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/window/window.cpp b/frameworks/window/window.cpp new file mode 100755 index 0000000..ef01ea3 --- /dev/null +++ b/frameworks/window/window.cpp @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "window/window.h" + +#include "window/window_impl.h" + +namespace OHOS { +Window* Window::CreateWindow(const WindowConfig& config) +{ + WindowImpl* window = new WindowImpl; + if (window != nullptr) { + if (!window->Create(config)) { + delete window; + return nullptr; + } + window->AddToDisplay(); + } + return window; +} + +void Window::DestoryWindow(Window* window) +{ + if (window != nullptr) { + WindowImpl* windowImpl = reinterpret_cast(window); + windowImpl->RemoveFromDisplay(); + windowImpl->UnbindRootView(); + windowImpl->Destory(); + delete windowImpl; + } +} +} \ No newline at end of file diff --git a/frameworks/window/window_impl.cpp b/frameworks/window/window_impl.cpp new file mode 100755 index 0000000..82be4cc --- /dev/null +++ b/frameworks/window/window_impl.cpp @@ -0,0 +1,227 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "window/window_impl.h" +#include "core/render_manager.h" +#include "dock/screen_device_proxy.h" +#include "graphic_log.h" +#include "iwindows_manager.h" + +namespace OHOS { +WindowImpl::WindowImpl() : rootView_(nullptr), iWindow_(nullptr), isShow_(false), gfxAlloc_({}) {} + +WindowImpl::~WindowImpl() {} + +bool WindowImpl::Create(const WindowConfig& config) +{ + GRAPHIC_LOGI("Create"); + if (iWindow_ == nullptr) { + config_ = config; + LiteWinConfig liteConfig; + liteConfig.rect = config.rect; + liteConfig.pixelFormat = IMAGE_PIXEL_FORMAT_ARGB8888; + liteConfig.opacity = config.opacity; + liteConfig.isModal = config.isModal; + liteConfig.compositeMode = static_cast(config.compositeMode); + iWindow_ = IWindowsManager::GetInstance()->CreateWindow(liteConfig); + if (iWindow_ == nullptr) { + return false; + } + } + return true; +} + +void WindowImpl::Destory() +{ + Flush(); + if (iWindow_ != nullptr) { + IWindowsManager::GetInstance()->RemoveWindow(iWindow_); + iWindow_ = nullptr; + } +} + +void WindowImpl::AddToDisplay() +{ + GRAPHIC_LOGI("AddToDisplay"); + RenderManager::GetInstance().AddToDisplay(this); +} + +void WindowImpl::RemoveFromDisplay() +{ + GRAPHIC_LOGI("RemoveFromDisplay"); + RenderManager::GetInstance().RemoveFromDisplay(this); +} + +void WindowImpl::BindRootView(RootView* rootView) +{ + if (rootView == nullptr) { + return; + } + UnbindRootView(); + GRAPHIC_LOGI("BindRootView"); + rootView_ = rootView; + rootView_->boundWindow_ = this; +} + +void WindowImpl::UnbindRootView() +{ + GRAPHIC_LOGI("UnbindRootView"); + if (rootView_ != nullptr) { + rootView_->boundWindow_ = nullptr; + rootView_ = nullptr; + } +} + +RootView* WindowImpl::GetRootView() +{ + return rootView_; +} + +Rect WindowImpl::GetRect() +{ + return config_.rect; +} + +void WindowImpl::Show() +{ + if (iWindow_ == nullptr) { + return; + } + + if (!isShow_) { + isShow_ = true; + Render(); + iWindow_->Show(); + } +} + +void WindowImpl::Hide() +{ + if (iWindow_ == nullptr) { + return; + } + + if (isShow_) { + isShow_ = false; + iWindow_->Hide(); + } +} + +void WindowImpl::MoveTo(int16_t x, int16_t y) +{ + GRAPHIC_LOGI("MoveTo"); + config_.rect.SetPosition(x, y); + if (iWindow_ != nullptr) { + iWindow_->MoveTo(x, y); + } +} + +void WindowImpl::Resize(int16_t width, int16_t height) +{ + GRAPHIC_LOGI("Resize"); + if ((width == config_.rect.GetWidth()) && (height == config_.rect.GetHeight())) { + return; + } + + config_.rect.Resize(width, height); + Flush(); + if (iWindow_ != nullptr) { + iWindow_->Resize(width, height); + } + + if (rootView_ != nullptr) { + rootView_->Invalidate(); + } +} + +void WindowImpl::RaiseToTop() +{ + GRAPHIC_LOGI("RaiseToTop"); + if (iWindow_ != nullptr) { + iWindow_->RaiseToTop(); + } +} + +void WindowImpl::LowerToBottom() +{ + GRAPHIC_LOGI("LowerToBottom"); + if (iWindow_ != nullptr) { + iWindow_->LowerToBottom(); + } +} + +void WindowImpl::Render() +{ + UpdateHalDisplayBuffer(); + if (gfxAlloc_.virAddr == nullptr) { + GRAPHIC_LOGE("window buffer is null, windId=%d", GetWindowId()); + return; + } + + if (rootView_ != nullptr) { + rootView_->Measure(); + rootView_->Render(); + } +} + +void WindowImpl::Update() +{ + if (iWindow_ == nullptr) { + return; + } + iWindow_->Update(); +} + +int32_t WindowImpl::GetWindowId() +{ + if (iWindow_ != nullptr) { + return iWindow_->GetWindowId(); + } else { + GRAPHIC_LOGE("iwindow is null!"); + return INVALID_WINDOW_ID; + } +} + +void WindowImpl::Flush() +{ + GRAPHIC_LOGI("Flush"); + if (iWindow_ == nullptr) { + return; + } + ISurface* surface = iWindow_->GetSurface(); + if (surface != nullptr) { + surface->Unlock(); + gfxAlloc_ = {}; + } +} + +void WindowImpl::UpdateHalDisplayBuffer() +{ + if ((gfxAlloc_.virAddr == nullptr) && (iWindow_ != nullptr)) { + ISurface* surface = iWindow_->GetSurface(); + if (surface == nullptr) { + return; + } + surface->Lock((void**)&gfxAlloc_.virAddr, (void**)&gfxAlloc_.phyAddr, &gfxAlloc_.stride); + } + AllocationInfo& gfxAlloc = ScreenDeviceProxy::GetInstance()->GetAllocationInfo(); + gfxAlloc.phyAddr = gfxAlloc_.phyAddr; + gfxAlloc.virAddr = gfxAlloc_.virAddr; + gfxAlloc.stride = gfxAlloc_.stride; + gfxAlloc.width = config_.rect.GetWidth(); + gfxAlloc.height = config_.rect.GetHeight(); + gfxAlloc.pixelFormat = IMAGE_PIXEL_FORMAT_ARGB8888; +} +} // namespace OHOS diff --git a/frameworks/window/window_impl.h b/frameworks/window/window_impl.h new file mode 100755 index 0000000..4ab9e6a --- /dev/null +++ b/frameworks/window/window_impl.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef GRAPHIC_LITE_WINDOW_IMPL_H +#define GRAPHIC_LITE_WINDOW_IMPL_H + +#include "iwindow.h" +#include "components/root_view.h" +#include "window/window.h" +#include "dock/screen_device.h" + +namespace OHOS { +class WindowImpl : public Window { +public: + WindowImpl(); + virtual ~WindowImpl(); + + void BindRootView(RootView* rootView) override; + void UnbindRootView() override; + RootView* GetRootView() override; + Rect GetRect() override; + + void Show() override; + void Hide() override; + void MoveTo(int16_t x, int16_t y) override; + void Resize(int16_t width, int16_t height) override; + void RaiseToTop() override; + void LowerToBottom() override; + + int32_t GetWindowId() override; + + void Render(); + void Update(); + void Flush(); + bool Create(const WindowConfig& config); + void Destory(); + void AddToDisplay(); + void RemoveFromDisplay(); + +private: + void UpdateHalDisplayBuffer(); + + RootView* rootView_; + IWindow* iWindow_; + WindowConfig config_; + bool isShow_; + AllocationInfo gfxAlloc_; +}; +} +#endif \ No newline at end of file diff --git a/interfaces/innerkits/common/graphic_startup.h b/interfaces/innerkits/common/graphic_startup.h new file mode 100755 index 0000000..c2776d7 --- /dev/null +++ b/interfaces/innerkits/common/graphic_startup.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef GRAPHIC_LITE_GRAPHIC_STARTUP_H +#define GRAPHIC_LITE_GRAPHIC_STARTUP_H +#include "heap_base.h" + +namespace OHOS { +class BaseFont; + +/** @brief Entry of graphic, mainly used to start graphic. */ +class GraphicStartUp : public HeapBase { +public: + static void Init(); + + static void InitFontEngine(uintptr_t psramAddr, uint32_t psramLen, const char* dPath, const char* ttfName); +}; +} // namespace OHOS +#endif // GRAPHIC_LITE_GRAPHIC_STARTUP_H diff --git a/interfaces/innerkits/common/image_decode_ability.h b/interfaces/innerkits/common/image_decode_ability.h new file mode 100755 index 0000000..1de2263 --- /dev/null +++ b/interfaces/innerkits/common/image_decode_ability.h @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef GRAPHIC_LITE_IMAGEDECODE_ABILITY_H +#define GRAPHIC_LITE_IMAGEDECODE_ABILITY_H +#include "heap_base.h" + +namespace OHOS { +enum { + IMG_SUPPORT_UNKNOW = 0x0, + IMG_SUPPORT_BITMAP = 0x01, + IMG_SUPPORT_JPEG = 0x02, + IMG_SUPPORT_PNG = 0x04, +}; +class ImageDecodeAbility : public HeapBase { +public: + static ImageDecodeAbility& GetInstance() + { + static ImageDecodeAbility instance; + return instance; + } + + void SetImageDecodeAbility(uint32_t imageType) + { + imageType_ = imageType; + } + + uint32_t GetImageDecodeAbility() + { + return imageType_; + } + +private: + ImageDecodeAbility() + { +#ifdef VERSION_STANDARD + imageType_ = IMG_SUPPORT_BITMAP | IMG_SUPPORT_JPEG | IMG_SUPPORT_PNG; +#else + imageType_ = IMG_SUPPORT_BITMAP; +#endif + } + ~ImageDecodeAbility() {} + + uint32_t imageType_; + + ImageDecodeAbility(const ImageDecodeAbility&) = delete; + ImageDecodeAbility& operator=(const ImageDecodeAbility&) = delete; + ImageDecodeAbility(ImageDecodeAbility&&) = delete; + ImageDecodeAbility& operator=(ImageDecodeAbility&&) = delete; +}; +} // namespace OHOS +#endif // GRAPHIC_LITE_IMAGEDECODE_ABILITY_H diff --git a/interfaces/innerkits/common/input_device_manager.h b/interfaces/innerkits/common/input_device_manager.h new file mode 100755 index 0000000..a732a26 --- /dev/null +++ b/interfaces/innerkits/common/input_device_manager.h @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef GRAPHIC_LITE_INPUT_DEVICE_MANAGER_H +#define GRAPHIC_LITE_INPUT_DEVICE_MANAGER_H + +#include "dock/input_device.h" +#include "list.h" +#include "common/task.h" + +namespace OHOS { +/** + * @brief Manage all input devices. + */ +class InputDeviceManager : public Task { +public: + /** + * @brief Get instance of InputDeviceManager. + * @returns Instance of InputDeviceManager + */ + static InputDeviceManager* GetInstance() + { + static InputDeviceManager instance; + return &instance; + } + + void Init() override; + + /** + * @brief Add an input device. + * + * @param [in] device Specific input device + */ + void Add(InputDevice* device); + + /** + * @brief Remove an input device. + * + * @param [in] Device Specific device to remove + */ + void Remove(InputDevice* device); + + /** + * Clear all display devices. + */ + void Clear(); + + void Callback() override; + +private: + InputDeviceManager() {} + ~InputDeviceManager() {} + + InputDeviceManager(const InputDeviceManager&) = delete; + InputDeviceManager& operator=(const InputDeviceManager&) = delete; + InputDeviceManager(InputDeviceManager&&) = delete; + InputDeviceManager& operator=(InputDeviceManager&&) = delete; + + List deviceList_; +}; +} // namespace OHOS +#endif // GRAPHIC_LITE_INPUT_DEVICE_MANAGER_H diff --git a/interfaces/innerkits/common/task_manager.h b/interfaces/innerkits/common/task_manager.h new file mode 100755 index 0000000..628bb14 --- /dev/null +++ b/interfaces/innerkits/common/task_manager.h @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef GRAPHIC_LITE_TASK_MANAGER_H +#define GRAPHIC_LITE_TASK_MANAGER_H + +#include + +#include "list.h" +#include "common/task.h" + +namespace OHOS { +class TaskManager : public HeapBase { +public: + /** + * @brief return TaskManager's singleton + * @return TaskManager* + */ + static TaskManager* GetInstance() + { + static TaskManager taskManager; + return &taskManager; + } + + /** + * @brief add task to task manager + * @param [in] task task pointer + */ + void Add(Task* task); + + /** + * @brief del task from task manager + * @param [in] task task pointer + */ + void Remove(Task* task); + + /** + * @brief set task run + * @param [in] enable task run + */ + void SetTaskRun(bool enable) + { + canTaskRun_ = enable; + } + + /** + * @brief get task run + * @return enable task run + */ + bool GetTaskRun() const + { + return canTaskRun_; + } + + /** + * @brief run all task + */ + void TaskHandler(); + + /** + * @brief reset the mutex of task handler, must be used carefully + */ + void ResetTaskHandlerMutex(); + +protected: + List list_; /* the task list */ + bool canTaskRun_; + bool isHandlerRunning_; + uint8_t idleLast_; + +private: + TaskManager() : canTaskRun_(false), isHandlerRunning_(false), idleLast_(0) {} + ~TaskManager() {} + + static const uint16_t IDLE_MEAS_PERIOD = 500; +}; +} // namespace OHOS +#endif // GRAPHIC_LITE_TASK_MANAGER_H diff --git a/interfaces/innerkits/dock/focus_manager.h b/interfaces/innerkits/dock/focus_manager.h new file mode 100644 index 0000000..a968d54 --- /dev/null +++ b/interfaces/innerkits/dock/focus_manager.h @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef GRAPHIC_LITE_FOCUS_MANAGER_H +#define GRAPHIC_LITE_FOCUS_MANAGER_H + +#include "components/ui_view.h" + +namespace OHOS { +#if ENABLE_MOTOR +/** + * @brief 震动类型. + * + * @since 5.0 + * @version 3.0 + */ +enum class MotorType { + MOTOR_TYPE_ONE, + MOTOR_TYPE_TWO, +}; + +/** + * @brief 震动函数. + * + * @param type 震动类型. + */ +typedef void(*MotorFunc)(MotorType motorType); +#endif + +class FocusManager { +public: + static FocusManager* GetInstance() + { + static FocusManager instance; + return &instance; + } + void ClearFocus() + { + view_ = nullptr; + } + + UIView* GetFocusedView() + { + return view_; + } + + void RequestFocus(UIView* view) + { + view_ = view; + } + +#if ENABLE_MOTOR + void RegisterMotorFunc(MotorFunc motorFunc) + { + motorFunc_ = motorFunc; + } + + MotorFunc GetMotorFunc() + { + return motorFunc_; + } +#endif + +private: + FocusManager() : view_(nullptr) {} + ~FocusManager() {} + UIView* view_; +#if ENABLE_MOTOR + MotorFunc motorFunc_ = nullptr; +#endif +}; +} // namespace OHOS +#endif // GRAPHIC_LITE_FOCUS_MANAGER_H diff --git a/interfaces/innerkits/dock/rotate_input_device.h b/interfaces/innerkits/dock/rotate_input_device.h new file mode 100755 index 0000000..6cfe68a --- /dev/null +++ b/interfaces/innerkits/dock/rotate_input_device.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef GRAPHIC_LITE_ROTATE_INPUT_DEVICE_H +#define GRAPHIC_LITE_ROTATE_INPUT_DEVICE_H + +#include "dock/input_device.h" +#include "components/ui_view.h" + +#if ENABLE_ROTATE_INPUT +namespace OHOS { +/** @brief A Rotate input device. */ +class RotateInputDevice : public InputDevice { +public: + /** @brief Constructor */ + RotateInputDevice(){}; + /** @brief Destructor */ + virtual ~RotateInputDevice(){}; + +protected: + void DispatchEvent(const DeviceData& data) override; +}; +} // namespace OHOS + +#endif // GRAPHIC_LITE_ROTATE_INPUT_DEVICE_H +#endif \ No newline at end of file diff --git a/interfaces/innerkits/font/ui_font_vector.h b/interfaces/innerkits/font/ui_font_vector.h new file mode 100755 index 0000000..312ef96 --- /dev/null +++ b/interfaces/innerkits/font/ui_font_vector.h @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef UI_FONT_VECTOR_H +#define UI_FONT_VECTOR_H +#include "font/base_font.h" +#include "graphic_config.h" +#include "ft2build.h" +#include "freetype/freetype.h" +#include "font/ui_font_cache.h" +#include + +namespace OHOS { +class UIFontVector : public BaseFont { +public: + UIFontVector(); + + ~UIFontVector(); + UIFontVector(const UIFontVector&) = delete; + UIFontVector& operator=(const UIFontVector&) noexcept = delete; + bool IsVectorFont() const override; + int8_t SetFontPath(const char* dpath, const char* spath) override; + int8_t SetCurrentFontId(uint8_t fontId, uint8_t size = 0) override; + uint16_t GetHeight() override; + uint8_t GetFontId(const char* ttfName, uint8_t size = 0) const override; + int16_t GetWidth(uint32_t unicode, uint8_t fontId) override; + uint8_t* GetBitmap(uint32_t unicode, GlyphNode& glyphNode, uint8_t fontId) override; + int8_t GetCurrentFontHeader(FontHeader& fontHeader) override; + int8_t GetGlyphNode(uint32_t unicode, GlyphNode& glyphNode) override; + uint8_t GetFontWeight(uint8_t fontId) override; + uint8_t GetShapingFontId(char* text, uint8_t& ttfId, uint32_t& script, + uint8_t fontId, uint8_t size) const override; + uint8_t RegisterFontInfo(const char* ttfName, uint8_t shaping = 0) override; + uint8_t RegisterFontInfo(const UITextLanguageFontParam* fontsTable, uint8_t num) override; + uint8_t UnregisterFontInfo(const char* ttfName) override; + uint8_t UnregisterFontInfo(const UITextLanguageFontParam* fontsTable, uint8_t num) override; + const UITextLanguageFontParam* GetFontInfo(uint8_t fontId) const override; + int32_t OpenVectorFont(uint8_t ttfId) override; + +private: + static constexpr uint8_t FONT_ID_MAX = 0xFF; + static constexpr uint8_t FONT_INVALID_TTF_ID = 0xFF; + static constexpr uint8_t TTF_NAME_LEN_MAX = 128; + static constexpr uint8_t FONT_BPP_8 = 8; + UITextLanguageFontParam fontInfo_[FONT_ID_MAX] = {{0}}; + std::string ttfDir_; + FT_Library ftLibrary_; + FT_Face ftFaces_[FONT_ID_MAX] = {0}; + bool freeTypeInited_; + uint32_t key_ = 0; + UIFontCache* bitmapCache_; + struct Metric { + int left; + int top; + int cols; + int rows; + int advance; + uint8_t buf[0]; + }; + void SetFace(FT_Face ftface, uint32_t unicode) const; + uint8_t GetFontId(uint32_t unicode) const; + uint32_t GetKey(uint8_t fontId, uint32_t size); + int8_t LoadGlyphIntoFace(uint8_t fontId, uint32_t unicode); + uint8_t IsGlyphFont(uint32_t unicode); +}; +} // namespace OHOS +#endif + diff --git a/interfaces/kits/animator/animator.h b/interfaces/kits/animator/animator.h new file mode 100755 index 0000000..54ff13e --- /dev/null +++ b/interfaces/kits/animator/animator.h @@ -0,0 +1,349 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +/** + * @addtogroup UI_Animator + * @{ + * + * @brief Defines UI animation effects and provides matched curves. + * + * @since 1.0 + * @version 1.0 + */ + +/** + * @file animator.h + * + * @brief Defines the attributes and common functions of the animator module. + * + * @since 1.0 + * @version 1.0 + */ + +#ifndef GRAPHIC_LITE_ANIMATOR_H +#define GRAPHIC_LITE_ANIMATOR_H + +#include +#include "components/ui_view.h" +#include "list.h" +#include "common/task.h" + +namespace OHOS { +class Animator; + +/** + * @brief Represents the animator callback. + * + * You need to implement the callback function to produce specific animator effects. + * + * @since 1.0 + * @version 1.0 + */ +class AnimatorCallback : public HeapBase { +public: + /** + * @brief Called when each frame starts. This is a pure virtual function, which needs your inheritance + * and implementation. + * + * @param view Indicates the UIView instance, which is added from the constructor of + * the Animator class. + * @since 1.0 + * @version 1.0 + */ + virtual void Callback(UIView* view) = 0; + + /** + * @brief Called when an animator stops. This is a pure virtual function, which needs your inheritance and + * implementation. + * + * @param view Indicates the UIView instance, which is added from the constructor of + * the Animator class. + * @since 1.0 + * @version 1.0 + */ + virtual void OnStop(UIView& view) {}; + + /** + * @brief A default destructor used to delete an AnimatorCallback instance. + * + * @since 1.0 + * @version 1.0 + */ + virtual ~AnimatorCallback() {} +}; + +/** + * @brief Represents an animator. + * + * This class is used to set the animator attributes, such as the duration, whether an animator is repeated, + * start and stop of an animator. + * + * @see Animator + * @since 1.0 + * @version 1.0 + */ +class Animator : public HeapBase { +public: + /** + * @brief Enumerates the states of this animator. + */ + enum : uint8_t { + /** Stop */ + STOP, + /** Start */ + START, + /** Pause */ + PAUSE, + /** Running (reserved and not used currently) */ + RUNNING + }; + + /** + * @brief A default constructor used to create an Animator instance. + * + * @since 1.0 + * @version 1.0 + */ + Animator() + : callback_(nullptr), view_(nullptr), state_(STOP), time_(0), repeat_(false), runTime_(0), lastRunTime_(0) {} + + /** + * @brief A constructor used to create an Animator instance. + * + * @param callback Indicates the animator callback for producing animator effects. + * For details, see {@link AnimatorCallback}. + * @param view Indicates the UIView instance bound to an animator, which can be used when invoking + * the animator callback. + * @param time Indicates the duration of this animator, in milliseconds. + * @param repeat Specifies whether to repeat this animator. true indicates the animator is repeated, + * and false (default value) indicates the animator is played once. + * @since 1.0 + * @version 1.0 + */ + Animator(AnimatorCallback* callback, UIView* view, uint32_t time, bool repeat) + : callback_(callback), view_(view), state_(STOP), time_(time), repeat_(repeat), runTime_(0), lastRunTime_(0) {} + + /** + * @brief A destructor used to delete the Animator instance. + * + * @since 1.0 + * @version 1.0 + */ + virtual ~Animator() {} + + /** + * @brief Starts this animator. + * + * @see Stop + * @since 1.0 + * @version 1.0 + */ + void Start(); + + /** + * @brief Stops this animator. + * + * @see Start + * @since 1.0 + * @version 1.0 + */ + void Stop(); + + /** + * @brief Pauses this animator. + * + * @see Resume + * @since 1.0 + * @version 1.0 + */ + void Pause(); + + /** + * @brief Resumes this animator from where it was paused. + * + * @see Pause + * @since 1.0 + * @version 1.0 + */ + void Resume(); + + /** + * @brief Obtains the current state of this animator. + * + * @return Returns the current animator state, which can be {@link START}, {@link STOP}, or {@link PAUSE}. + * @see SetState + * @since 1.0 + * @version 1.0 + */ + uint8_t GetState() const + { + return state_; + } + + /** + * @brief Sets the current state for this animator. + * + * @param state Indicates the current animator state to set, which can be {@link STOP}, {@link START}, + * or {@link PAUSE}. + * @see GetState + * @since 1.0 + * @version 1.0 + */ + void SetState(uint8_t state) + { + state_ = state; + } + + /** + * @brief Obtains the total duration of this animator. + * + * @return Returns the total duration. + * @see SetTime + * @since 1.0 + * @version 1.0 + */ + uint32_t GetTime() const + { + return time_; + } + + /** + * @brief Sets the total duration for this animator. + * + * @param time Indicates the total duration to set, in milliseconds. + * @see GetTime + * @since 1.0 + * @version 1.0 + */ + void SetTime(uint32_t time) + { + time_ = time; + } + + /** + * @brief Obtains the running time of this animator. + * + * @return Returns the running time. + * @see SetRunTime + * @since 1.0 + * @version 1.0 + */ + uint32_t GetRunTime() const + { + return runTime_; + } + + /** + * @brief Sets the running time for this animator. + * + * @param runTime Indicates the running time to set, in milliseconds. + * @see GetRunTime + * @since 1.0 + * @version 1.0 + */ + void SetRunTime(uint32_t runTime) + { + runTime_ = runTime; + } + + /** + * @brief Checks whether this animator is repeated. + * + * @return Returns true if the animator is repeated; returns false if the animator is played once. + * @since 1.0 + * @version 1.0 + */ + bool IsRepeat() const + { + return repeat_; + } + + void Run(); + +protected: + AnimatorCallback* callback_; + UIView* view_; + uint8_t state_; + uint32_t time_; + bool repeat_; + uint32_t runTime_; + uint32_t lastRunTime_; +}; + +/** + * @brief Represents the animator manager. + * + * This is a singleton class used to manage Animator instances. + * + * @see Task + * @since 1.0 + * @version 1.0 + */ +class AnimatorManager : public Task { +public: + /** + * @brief Obtains the AnimatorManager instance. + * + * @return Returns the AnimatorManager instance. + * @since 1.0 + * @version 1.0 + */ + static AnimatorManager* GetInstance() + { + static AnimatorManager animatorManager; + return &animatorManager; + } + + void Init() override; + + /** + * @brief Adds the Animator instance to the AnimatorManager linked list for management, + * so that the {@link Run} function of the Animator class is called once for each frame. + * + * @param animator Indicates the pointer to the Animator instance to add. + * @see Remove + * @since 1.0 + * @version 1.0 + */ + void Add(Animator* animator); + + /** + * @brief Removes the Animator instance from the AnimatorManager linked list. + * + * @param animator Indicates the pointer to the Animator instance to remove. + * @see Add + * @since 1.0 + * @version 1.0 + */ + void Remove(const Animator* animator); + + void AnimatorTask(); + + void Callback() override + { + AnimatorTask(); + } + +protected: + List list_; + AnimatorManager() {} + virtual ~AnimatorManager() {} + AnimatorManager(const AnimatorManager&) = delete; + AnimatorManager& operator=(const AnimatorManager&) = delete; + AnimatorManager(AnimatorManager&&) = delete; + AnimatorManager& operator=(AnimatorManager&&) = delete; +}; +} +#endif diff --git a/interfaces/kits/animator/easing_equation.h b/interfaces/kits/animator/easing_equation.h new file mode 100755 index 0000000..e28f121 --- /dev/null +++ b/interfaces/kits/animator/easing_equation.h @@ -0,0 +1,425 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +/** + * @addtogroup UI_Animator + * @{ + * + * @brief Defines UI animation effects and provides matched curves. + * + * @since 1.0 + * @version 1.0 + */ + +/** + * @file easing_equation.h + * + * @brief Defines the attributes and functions of the animation easing module. + * + * @since 1.0 + * @version 1.0 + */ + +#ifndef GRAPHIC_LITE_EASING_EQUATION_H +#define GRAPHIC_LITE_EASING_EQUATION_H + +#include "heap_base.h" +#include + +namespace OHOS { +/** + * @brief Calculates the value for the current time of an animation. + * + * @param startPos Indicates the start value of this animation. + * @param endPos Indicates the end value of this animation. + * @param curTime Indicates the current time of this animation. + * @param durationTime Indicates the total duration of this animation. + * + * @brief Returns the value for the current time. + */ +typedef int16_t (*EasingFunc)(int16_t startPos, int16_t endPos, uint16_t curTime, uint16_t durationTime); + +/** + * @brief Defines functions for specifying the velocity of an animation. + * + * @since 1.0 + * @version 1.0 + */ +class EasingEquation : public HeapBase { +public: + /** + * @brief Sets the parameter s in the equation (s+1)*t^3 - s*t^2 for a back easing. + * + * A larger s indicates a larger degree of overshoot. The default value is 1.7. You are advised to set + * this parameter to a value ranging from 1 to 4. The setting takes effect for all the back-ease animations. + * + * @param overshoot Indicates the overshoot s in the equation to set. + * @see BackEaseIn | BackEaseOut | BackEaseInOut + * @since 1.0 + * @version 1.0 + */ + static void SetBackOvershoot(double overshoot); + + /** + * @brief Eases in with an overshoot. + * + * (s+1)*t^3 - s*t^2 is the equation for a back easing. + * The animation moves back slightly at the beginning and then accelerates towards the end. + * + * @param startPos Indicates the start value of this animation. + * @param endPos Indicates the end value of this animation. + * @param curTime Indicates the current time of this animation. + * @param durationTime Indicates the total duration of this animation. + * + * @return Returns the value for the current time. + * @see SetBackOvershoot | BackEaseOut | BackEaseInOut + * @since 1.0 + * @version 1.0 + */ + static int16_t BackEaseIn(int16_t startPos, int16_t endPos, uint16_t curTime, uint16_t durationTime); + + /** + * @brief Eases out with an overshoot. + * + * (s+1)*t^3 - s*t^2 is the equation for a back easing. + * The animation moves towards the end, slightly exceeds it and finally comes back. + * + * @param startPos Indicates the start value of this animation. + * @param endPos Indicates the end value of this animation. + * @param curTime Indicates the current time of this animation. + * @param durationTime Indicates the total duration of this animation. + * + * @return Returns the value for the current time. + * @see SetBackOvershoot | BackEaseIn | BackEaseInOut + * @since 1.0 + * @version 1.0 + */ + static int16_t BackEaseOut(int16_t startPos, int16_t endPos, uint16_t curTime, uint16_t durationTime); + + /** + * @brief Eases in and then out with an overshoot. + * + * (s+1)*t^3 - s*t^2 is the equation for a back easing. The animation slightly moves back at the beginning, + * goes towards the end, slightly exceeds it and finally comes back. + * + * @param startPos Indicates the start value of this animation. + * @param endPos Indicates the end value of this animation. + * @param curTime Indicates the current time of this animation. + * @param durationTime Indicates the total duration of this animation. + * + * @return Returns the value for the current time. + * @see SetBackOvershoot | BackEaseIn | BackEaseOut + * @since 1.0 + * @version 1.0 + */ + static int16_t BackEaseInOut(int16_t startPos, int16_t endPos, uint16_t curTime, uint16_t durationTime); + + /** + * @brief Eases in shaping like a circular curve. + * + * sqrt(1-t^2) is the equation for a circular easing. The animation starts slowly from zero velocity and + * accelerates fast towards the end. The acceleration change is similar to a circular curve. + * + * @param startPos Indicates the start value of this animation. + * @param endPos Indicates the end value of this animation. + * @param curTime Indicates the current time of this animation. + * @param durationTime Indicates the total duration of this animation. + * + * @return Returns the value for the current time. + * @see CircEaseOut | CircEaseInOut + * @since 1.0 + * @version 1.0 + */ + static int16_t CircEaseIn(int16_t startPos, int16_t endPos, uint16_t curTime, uint16_t durationTime); + + /** + * @brief Eases out shaping like a circular curve. + * + * sqrt(1-t^2) is the equation for a circular easing. The animation starts fast and decelerates slowly + * towards the end. The acceleration change is similar to a circular curve. + * + * @param startPos Indicates the start value of this animation. + * @param endPos Indicates the end value of this animation. + * @param curTime Indicates the current time of this animation. + * @param durationTime Indicates the total duration of this animation. + * + * @return Returns the value for the current time. + * @see CircEaseIn | CircEaseInOut + * @since 1.0 + * @version 1.0 + */ + static int16_t CircEaseOut(int16_t startPos, int16_t endPos, uint16_t curTime, uint16_t durationTime); + + /** + * @brief Eases in and then out shaping like a circular curve. + * + * sqrt(1-t^2) is the equation for a circular easing. The animation accelerates slowly until halfway and + * decreases slowly towards the end. The acceleration change is similar to a circular curve. + * + * @param startPos Indicates the start value of this animation. + * @param endPos Indicates the end value of this animation. + * @param curTime Indicates the current time of this animation. + * @param durationTime Indicates the total duration of this animation. + * + * @return Returns the value for the current time. + * @see CircEaseIn | CircEaseOut + * @since 1.0 + * @version 1.0 + */ + static int16_t CircEaseInOut(int16_t startPos, int16_t endPos, uint16_t curTime, uint16_t durationTime); + + /** + * @brief Eases in shaping like a cubic curve. + * + * t^3 is the equation for a cubic easing. The animation starts slowly from zero velocity and accelerates + * fast towards the end. The acceleration change is similar to a cubic curve. + * + * @param startPos Indicates the start value of this animation. + * @param endPos Indicates the end value of this animation. + * @param curTime Indicates the current time of this animation. + * @param durationTime Indicates the total duration of this animation. + * + * @return Returns the value for the current time. + * @see CubicEaseOut | CubicEaseInOut + * @since 1.0 + * @version 1.0 + */ + static int16_t CubicEaseIn(int16_t startPos, int16_t endPos, uint16_t curTime, uint16_t durationTime); + + /** + * @brief Eases out shaping like a cubic curve. + * + * t^3 is the equation for a cubic easing. The animation starts fast and decelerates slowly + * towards the end. The acceleration change is similar to a cubic curve. + * + * @param startPos Indicates the start value of this animation. + * @param endPos Indicates the end value of this animation. + * @param curTime Indicates the current time of this animation. + * @param durationTime Indicates the total duration of this animation. + * + * @return Returns the value for the current time. + * @see CubicEaseIn | CubicEaseInOut + * @since 1.0 + * @version 1.0 + */ + static int16_t CubicEaseOut(int16_t startPos, int16_t endPos, uint16_t curTime, uint16_t durationTime); + + /** + * @brief Eases in and then out shaping like a cubic curve. + * + * t^3 is the equation for a cubic easing. The animation accelerates slowly until halfway + * and decelerates slowly towards the end. The acceleration change is similar to a cubic curve. + * + * @param startPos Indicates the start value of this animation. + * @param endPos Indicates the end value of this animation. + * @param curTime Indicates the current time of this animation. + * @param durationTime Indicates the total duration of this animation. + * + * @return Returns the value for the current time. + * @see CubicEaseIn | CubicEaseOut + * @since 1.0 + * @version 1.0 + */ + static int16_t CubicEaseInOut(int16_t startPos, int16_t endPos, uint16_t curTime, uint16_t durationTime); + + /** + * @brief Displays no linear easing effects. + * + * t is the equation for a linear easing. The animation progresses at a constant velocity towards the end. + * + * @param startPos Indicates the start value of this animation. + * @param endPos Indicates the end value of this animation. + * @param curTime Indicates the current time of this animation. + * @param durationTime Indicates the total duration of this animation. + * + * @return Returns the value for the current time. + * @see LinearEaseIn | LinearEaseOut | LinearEaseInOut + * @since 1.0 + * @version 1.0 + */ + static int16_t LinearEaseNone(int16_t startPos, int16_t endPos, uint16_t curTime, uint16_t durationTime); + + /** + * @brief Eases in shaping like a quadratic curve. + * + * t^2 is the equation for a quadratic easing. The animation starts slowly from zero velocity and + * accelerates fast towards the end. The acceleration change is similar to a quadratic curve. + * + * @param startPos Indicates the start value of this animation. + * @param endPos Indicates the end value of this animation. + * @param curTime Indicates the current time of this animation. + * @param durationTime Indicates the total duration of this animation. + * + * @return Returns the value for the current time. + * @see QuadEaseOut | QuadEaseInOut + * @since 1.0 + * @version 1.0 + */ + static int16_t QuadEaseIn(int16_t startPos, int16_t endPos, uint16_t curTime, uint16_t durationTime); + + /** + * @brief Eases out shaping like a quadratic curve. + * + * t^2 is the equation for a quadratic easing. The animation starts fast and decelerates slowly + * towards the end. The acceleration change is similar to a quadratic curve. + * + * @param startPos Indicates the start value of this animation. + * @param endPos Indicates the end value of this animation. + * @param curTime Indicates the current time of this animation. + * @param durationTime Indicates the total duration of this animation. + * + * @return Returns the value for the current time. + * @see QuadEaseIn | QuadEaseInOut + * @since 1.0 + * @version 1.0 + */ + static int16_t QuadEaseOut(int16_t startPos, int16_t endPos, uint16_t curTime, uint16_t durationTime); + + /** + * @brief Eases in and then out shaping like a quadratic curve. + * + * t^2 is the equation for a quadratic easing. The animation accelerates slowly until halfway + * and decelerates slowly towards the end. The acceleration change is similar to a quadratic curve. + * + * @param startPos Indicates the start value of this animation. + * @param endPos Indicates the end value of this animation. + * @param curTime Indicates the current time of this animation. + * @param durationTime Indicates the total duration of this animation. + * + * @return Returns the value for the current time. + * @see QuadEaseIn | QuadEaseOut + * @since 1.0 + * @version 1.0 + */ + static int16_t QuadEaseInOut(int16_t startPos, int16_t endPos, uint16_t curTime, uint16_t durationTime); + + /** + * @brief Eases in shaping like a quintic curve. + * + * t^5 is the equation for a quintic easing. The animation starts slowly from zero velocity and + * accelerates fast towards the end. The acceleration change is similar to a quintic curve. + * + * @param startPos Indicates the start value of this animation. + * @param endPos Indicates the end value of this animation. + * @param curTime Indicates the current time of this animation. + * @param durationTime Indicates the total duration of this animation. + * + * @return Returns the value for the current time. + * @see QuintEaseOut | QuintEaseInOut + * @since 1.0 + * @version 1.0 + */ + static int16_t QuintEaseIn(int16_t startPos, int16_t endPos, uint16_t curTime, uint16_t durationTime); + + /** + * @brief Eases out shaping like a quintic curve. + * + * t^5 is the equation for a quintic easing. The animation starts fast and decelerates slowly + * towards the end. The acceleration change is similar to a quintic curve. + * + * @param startPos Indicates the start value of this animation. + * @param endPos Indicates the end value of this animation. + * @param curTime Indicates the current time of this animation. + * @param durationTime Indicates the total duration of this animation. + * + * @return Returns the value for the current time. + * @see QuintEaseIn | QuintEaseInOut + * @since 1.0 + * @version 1.0 + */ + static int16_t QuintEaseOut(int16_t startPos, int16_t endPos, uint16_t curTime, uint16_t durationTime); + + /** + * @brief Eases in and then out shaping like a quintic curve. + * + * t^5 is the equation for a quintic easing. The animation accelerates slowly until halfway and + * decelerates slowly towards the end. The acceleration change is similar to a quintic curve. + * + * @param startPos Indicates the start value of this animation. + * @param endPos Indicates the end value of this animation. + * @param curTime Indicates the current time of this animation. + * @param durationTime Indicates the total duration of this animation. + * + * @return Returns the value for the current time. + * @see QuintEaseIn | QuintEaseOut + * @since 1.0 + * @version 1.0 + */ + static int16_t QuintEaseInOut(int16_t startPos, int16_t endPos, uint16_t curTime, uint16_t durationTime); + + /** + * @brief Eases in shaping like a sinusoidal curve. + * + * sin(t) is the equation for a sinusoidal easing. The animation starts slowly from zero velocity + * and accelerates fast towards the end. The acceleration change is similar to a sinusoidal curve. + * + * @param startPos Indicates the start value of this animation. + * @param endPos Indicates the end value of this animation. + * @param curTime Indicates the current time of this animation. + * @param durationTime Indicates the total duration of this animation. + * + * @return Returns the value for the current time. + * @see SineEaseOut | SineEaseInOut + * @since 1.0 + * @version 1.0 + */ + static int16_t SineEaseIn(int16_t startPos, int16_t endPos, uint16_t curTime, uint16_t durationTime); + + /** + * @brief Eases out shaping like a sinusoidal curve. + * + * sin(t) is the equation for a sinusoidal easing. The animation starts fast and decelerates + * slowly towards the end. The acceleration change is similar to a sinusoidal curve. + * + * @param startPos Indicates the start value of this animation. + * @param endPos Indicates the end value of this animation. + * @param curTime Indicates the current time of this animation. + * @param durationTime Indicates the total duration of this animation. + * + * @return Returns the value for the current time. + * @see SineEaseIn | SineEaseInOut + * @since 1.0 + * @version 1.0 + */ + static int16_t SineEaseOut(int16_t startPos, int16_t endPos, uint16_t curTime, uint16_t durationTime); + + /** + * @brief Eases in and then out shaping like a sinusoidal curve. + * + * sin(t) is the equation for a sinusoidal easing. The animation accelerates slowly until + * halfway and decelerates slowly towards the end. The acceleration change is similar to a sinusoidal curve. + * + * @param startPos Indicates the start value of this animation. + * @param endPos Indicates the end value of this animation. + * @param curTime Indicates the current time of this animation. + * @param durationTime Indicates the total duration of this animation. + * + * @return Returns the value for the current time. + * @see SineEaseIn | SineEaseOut + * @since 1.0 + * @version 1.0 + */ + static int16_t SineEaseInOut(int16_t startPos, int16_t endPos, uint16_t curTime, uint16_t durationTime); + +private: + static constexpr uint16_t INTERPOLATION_RANGE = 1024; + static constexpr uint16_t INTERPOLATION_RANGE_OFFSET = 10; + static constexpr uint32_t INTERPOLATION_RANGE_SQUARE = 1048576; + static constexpr double OVERSHOOT_MAX = 4; + static constexpr double OVERSHOOT_MIN = 1; + static double overshoot_; +}; +} // namespace OHOS +#endif diff --git a/interfaces/kits/animator/interpolation.h b/interfaces/kits/animator/interpolation.h new file mode 100755 index 0000000..0aa6f5f --- /dev/null +++ b/interfaces/kits/animator/interpolation.h @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +/** + * @addtogroup UI_Animator + * @{ + * + * @brief Defines UI animation effects and provides matched curves. + * + * @since 1.0 + * @version 1.0 + */ + +/** + * @file interpolation.h + * + * @brief Defines the functions for calculating the interpolation in computer graphics. + * + * @since 1.0 + * @version 1.0 + */ + +#ifndef GRAPHIC_LITE_INTERPOLATION_H +#define GRAPHIC_LITE_INTERPOLATION_H + +#include "heap_base.h" + +namespace OHOS { +/** + * @brief Calculates the Bezier interpolation. + * + * @since 1.0 + * @version 1.0 + */ +class Interpolation : public HeapBase { +public: + /** + * @brief Obtains the value calculated by the cubic Bezier equation. + * + * Use [0, 1024] instead of [0, 1] in the standard Bezier equation. The cubic Bezier equation + * is B(t) = P0*(1-t)^3 + 3*P1*t*(1-t)^2 + 3*P2*t^2*(1-t) + P3*t^3. + * + * @param t Indicates the current change rate of the cubic Bezier curve, within [0, 1024]. + * @param u0 Indicates the coordinates for the start point of the cubic Bezier curve, within [0, 1024]. + * @param u1 Indicates the coordinates for the first control point of the cubic Bezier curve, within [0, 1024]. + * @param u2 Indicates the coordinates for the second control point of the cubic Bezier curve, within [0, 1024]. + * @param u3 Indicates the coordinates for the end point of the cubic Bezier curve, within [0, 1024]. + * + * @return Returns the coordinates for the current change rate. + * @since 1.0 + * @version 1.0 + */ + static int16_t GetBezierInterpolation(int16_t t, int16_t u0, int16_t u1, int16_t u2, int16_t u3); + +private: + constexpr static uint16_t BESSEL_COEFFICIENT = 3; + constexpr static uint16_t INTERPOLATION_RANGE = 1024; + constexpr static uint16_t CUBIC_BEZIER_CALCULATE_OFFSET = 30; +}; +} // namespace OHOS +#endif // GRAPHIC_LITE_INTERPOLATION_H diff --git a/interfaces/kits/common/image.h b/interfaces/kits/common/image.h new file mode 100755 index 0000000..33384f2 --- /dev/null +++ b/interfaces/kits/common/image.h @@ -0,0 +1,169 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +/** + * @addtogroup UI_Common + * @{ + * + * @brief Defines common UI capabilities, such as image and text processing. + * + * @since 1.0 + * @version 1.0 + */ + +/** + * @file image.h + * + * @brief Declares basic image attributes, including the image type and path. + * + * @since 1.0 + * @version 1.0 + */ + +#ifndef GRAPHIC_LITE_IMAGE_H +#define GRAPHIC_LITE_IMAGE_H + +#include "geometry2d.h" +#include "heap_base.h" +#include "image_info.h" +#include "style.h" + +namespace OHOS { +/** + * @brief Represents basic image attributes, including the image type and path. + * + * @since 1.0 + * @version 1.0 + */ +class Image : public HeapBase { +public: + /** + * @brief A constructor used to create an Image instance. You can use this constructor when a component + * requires a map. + * + * @since 1.0 + * @version 1.0 + */ + Image(); + + /** + * @brief A destructor used to delete the Image instance. + * + * @since 1.0 + * @version 1.0 + */ + virtual ~Image(); + + /** + * @brief Obtains the image information in an array. + * + * @return Returns the pointer to the image information. + * @since 1.0 + * @version 1.0 + */ + const ImageInfo* GetImageInfo() const + { + return imageInfo_; + } + + /** + * @brief Obtains the image path in binary. + * + * @return Returns the pointer to the image path. + * @since 1.0 + * @version 1.0 + */ + const char* GetPath() const + { + return path_; + } + + /** + * @brief Obtains the basic image information, including the image format, width, and height. + * + * @param header Indicates the basic image information. + * @since 1.0 + * @version 1.0 + */ + void GetHeader(ImageHeader& header) const; + + /** + * @brief Obtains the image type. + * + * @return Returns IMG_SRC_VARIABLE for image information in an array; returns IMG_SRC_FILE for an + * image path in binary. + * @since 1.0 + * @version 1.0 + */ + uint8_t GetSrcType() const + { + return srcType_; + } + + /** + * @brief Sets the image path. + * + * @param src Indicates the pointer to image path in the format of ..\\xxx\\xxx\\xxx.bin. + * @return Returns true if the operation is successful; returns false if the operation fails. + * @since 1.0 + * @version 1.0 + */ + bool SetSrc(const char* src); + + /** + * @brief Sets the image information. + * + * @param src Indicates the pointer to the image information. + * @return Returns true if the operation is successful; returns false if the operation fails. + * @since 1.0 + * @version 1.0 + */ + bool SetSrc(const ImageInfo* src); + + void DrawImage(const Rect& coords, const Rect& mask, const Style& style, uint8_t opaScale) const; + +protected: + const ImageInfo* imageInfo_; + const char* path_; + +private: +#if ENABLE_JPEG_AND_PNG + enum ImageType { + IMG_PNG, + IMG_JPEG, + IMG_UNKNOWN, + }; + + const static uint8_t IMG_BYTES_TO_CHECK = 4; // 4: check 4 bytes of image file +#endif + + uint8_t srcType_; + bool mallocFlag_; + bool SetLiteSrc(const char* src); + bool SetStandardSrc(const char* src); +#if ENABLE_JPEG_AND_PNG + bool SetPNGSrc(const char* src); + bool SetJPEGSrc(const char* src); + ImageType CheckImgType(const char* src); +#endif + bool IsImgValid(const char* suffix) + { + return (!strcmp(suffix, ".png") || !strcmp(suffix, ".PNG") || !strcmp(suffix, ".jpg") || + !strcmp(suffix, ".JPG") || !strcmp(suffix, ".jpeg") || !strcmp(suffix, ".JPEG") || + !strcmp(suffix, ".BMP") || !strcmp(suffix, ".bmp")); + } +}; +} // namespace OHOS +#endif // GRAPHIC_LITE_IMAGE_H diff --git a/interfaces/kits/common/screen.h b/interfaces/kits/common/screen.h new file mode 100755 index 0000000..038362e --- /dev/null +++ b/interfaces/kits/common/screen.h @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +/** + * @addtogroup UI_Common + * @{ + * + * @brief Defines common UI capabilities, such as image and text processing. + * + * @since 1.0 + * @version 1.0 + */ + +/** + * @file screen.h + * + * @brief Declares the screen information. + * + * @since 1.0 + * @version 1.0 + */ + +#ifndef GRAPHIC_LITE_SCREEN_H +#define GRAPHIC_LITE_SCREEN_H + +#include "heap_base.h" + +namespace OHOS { +/** + * @brief Represents the screen info of the device. + * + * @since 1.0 + * @version 1.0 + */ +class Screen : HeapBase { +public: + /** + * @brief Obtains a singleton Screen instance. + * @return Returns the Screen instance. + */ + static Screen& GetInstance() + { + static Screen instance; + return instance; + } + + /** + * @brief Obtains the width of this screen. + * + * @return Returns the screen width. + * @since 1.0 + * @version 1.0 + */ + uint16_t GetWidth(); + + /** + * @brief Obtains the height of this screen. + * + * @return Returns the screen height. + * @since 1.0 + * @version 1.0 + */ + uint16_t GetHeight(); + +private: + Screen() {} + virtual ~Screen() {} +}; +} // namespace OHOS +#endif // GRAPHIC_LITE_SCREEN_H \ No newline at end of file diff --git a/interfaces/kits/common/task.h b/interfaces/kits/common/task.h new file mode 100755 index 0000000..cd11f3f --- /dev/null +++ b/interfaces/kits/common/task.h @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +/** + * @addtogroup UI_Common + * @{ + * + * @brief Defines common UI capabilities, such as image and text processing. + * + * @since 1.0 + * @version 1.0 + */ + +/** + * @file task.h + * + * @brief Declares the Task class of the graphics module, which provides functions for setting the running period + * and time of a task. + * + * @since 1.0 + * @version 1.0 + */ + +#ifndef GRAPHIC_LITE_TASK_H +#define GRAPHIC_LITE_TASK_H + +#include + +#include "heap_base.h" + +namespace OHOS { +/** + * @brief Represents the Task class of the graphics module. + * This class provides functions for setting the running period and time of a task. + * + * @since 1.0 + * @version 1.0 + */ +class Task : public HeapBase { +public: + /** + * @brief A constructor used to create a Task instance. + */ + Task() : period_(DEFAULT_TASK_PERIOD), lastRun_(0) {} + + /** + * @brief A constructor used to create a Task instance with the specified running period. + * @param period Indicates the running period of this task. + */ + Task(uint32_t period) : period_(period), lastRun_(0) {} + + /** + * @brief A destructor used to delete the Task instance. + */ + virtual ~Task() {} + + /** + * @brief Sets the running period for this task. + * @param period Indicates the running period to set. + */ + void SetPeriod(uint32_t period) + { + period_ = period; + } + + /** + * @brief Sets the end time for this task. + * @param lastRun Indicates the end time to set. + */ + void SetLastRun(uint32_t lastRun) + { + lastRun_ = lastRun; + } + + /** + * @brief Obtains the running period of this task. + * @return Returns the running period. + */ + uint32_t GetPeriod() const + { + return period_; + } + + /** + * @brief Obtains the end time of this task. + * @return Returns the end time. + */ + uint32_t GetLastRun() const + { + return lastRun_; + } + + /** + * @brief Executes this task. + */ + void TaskExecute(); + + /** + * @brief Called when this task is executed. + */ + virtual void Callback() = 0; + + /** + * @brief Initializes this task. + */ + virtual void Init(); + +protected: + uint32_t period_; /* call period in ms unit */ + uint32_t lastRun_; /* last run time */ +}; +} // namespace OHOS +#endif // GRAPHIC_LITE_TASK_H \ No newline at end of file diff --git a/interfaces/kits/common/text.h b/interfaces/kits/common/text.h new file mode 100755 index 0000000..1a5af81 --- /dev/null +++ b/interfaces/kits/common/text.h @@ -0,0 +1,367 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +/** + * @addtogroup UI_Common + * @{ + * + * @brief Defines common UI capabilities, such as image and text processing. + * + * @since 1.0 + * @version 1.0 + */ + +/** + * @file text.h + * + * @brief Declares the Text class that provides functions to set basic text attributes, such as the text + * direction and alignment mode. + * + * @since 1.0 + * @version 1.0 + */ + +#ifndef GRAPHIC_LITE_TEXT_H +#define GRAPHIC_LITE_TEXT_H + +#include "geometry2d.h" +#include "graphic_types.h" +#include "style.h" + +namespace OHOS { +/** + * @brief Enumerates text alignment modes. + */ +enum UITextLanguageAlignment : uint8_t { + /** Left-aligned */ + TEXT_ALIGNMENT_LEFT = 0, + /** Right-aligned */ + TEXT_ALIGNMENT_RIGHT, + /** Centered */ + TEXT_ALIGNMENT_CENTER, + /** Top-aligned */ + TEXT_ALIGNMENT_TOP, + /** Bottom-aligned */ + TEXT_ALIGNMENT_BOTTOM, +}; + +/** + * @brief Enumerates text directions. + */ +enum UITextLanguageDirect : uint8_t { + /** Left-to-right */ + TEXT_DIRECT_LTR = 0, + /** Right-to-left */ + TEXT_DIRECT_RTL, + TEXT_DIRECT_MIXED, +}; + +/** + * @brief Represents the base class of Text, providing the text attribute setting and text drawing + * capabilities for components that require font display. + * + * @since 1.0 + * @version 1.0 + */ +class Text : public HeapBase { +public: + /** Invalid value for the ellipsis position */ + static constexpr uint16_t TEXT_ELLIPSIS_END_INV = 0xFFFF; + + /** + * @brief A constructor used to create a Text instance. + * + * @since 1.0 + * @version 1.0 + */ + Text(); + + /** + * @brief A destructor used to delete the Text instance. + * + * @since 1.0 + * @version 1.0 + */ + virtual ~Text(); + + /** + * @brief Sets the content for this text. + * + * @param text Indicates the pointer to the text content. + * @since 1.0 + * @version 1.0 + */ + virtual void SetText(const char* text); + + /** + * @brief Obtains the content of this text. + * + * @return Returns the text content. + * @since 1.0 + * @version 1.0 + */ + const char* GetText() const + { + return text_; + } + + /** + * @brief Sets the font name and size. + * + * @param name Indicates the pointer to the font name. + * @param size Indicates the font size to set. + * @since 1.0 + * @version 1.0 + */ + void SetFont(const char* name, uint8_t size); + + static void SetFont(const char* name, uint8_t size, char*& destName, uint8_t& destSize); + + /** + * @brief Sets the font ID. + * + * @param fontId Indicates the font ID to set. + * @since 1.0 + * @version 1.0 + */ + void SetFontId(uint8_t fontId); + + /** + * @brief Obtains the font ID. + * + * @return Returns the front ID. + * @since 1.0 + * @version 1.0 + */ + uint8_t GetFontId() const + { + return fontId_; + } + + /** + * @brief Obtains the font size. + * + * @return Returns the front size. + * @since 1.0 + * @version 1.0 + */ + uint8_t GetFontSize() const + { + return fontSize_; + } + + /** + * @brief Sets the direction for this text. + * + * @param direct Indicates the text direction, as defined in {@link UITextLanguageDirect}. + * @since 1.0 + * @version 1.0 + */ + void SetDirect(UITextLanguageDirect direct) + { + direct_ = direct; + } + + /** + * @brief Obtains the direction of this text. + * + * @return Returns the text direction, as defined in {@link UITextLanguageDirect}. + * @since 1.0 + * @version 1.0 + */ + UITextLanguageDirect GetDirect() const + { + return static_cast(direct_); + } + + /** + * @brief Sets the alignment mode for this text. + * + * @param horizontalAlign Indicates the horizontal alignment mode to set, + * which can be {@link TEXT_ALIGNMENT_LEFT}, + * {@link TEXT_ALIGNMENT_CENTER}, or {@link TEXT_ALIGNMENT_RIGHT}. + * @param verticalAlign Indicates the vertical alignment mode to set, which can be + * {@link TEXT_ALIGNMENT_TOP} (default mode), {@link TEXT_ALIGNMENT_CENTER}, + * or {@link TEXT_ALIGNMENT_BOTTOM}. + * @since 1.0 + * @version 1.0 + */ + void SetAlign(UITextLanguageAlignment horizontalAlign, UITextLanguageAlignment verticalAlign = TEXT_ALIGNMENT_TOP) + { + if ((horizontalAlign_ != horizontalAlign) || (verticalAlign_ != verticalAlign)) { + needRefresh_ = true; + horizontalAlign_ = horizontalAlign; + verticalAlign_ = verticalAlign; + } + } + + /** + * @brief Obtains the horizontal alignment mode. + * + * @return Returns the horizontal alignment mode. + * @since 1.0 + * @version 1.0 + */ + UITextLanguageAlignment GetHorAlign() const + { + return static_cast(horizontalAlign_); + } + + /** + * @brief Obtains the vertical alignment mode. + * + * @return Returns the vertical alignment mode. + * @since 1.0 + * @version 1.0 + */ + UITextLanguageAlignment GetVerAlign() const + { + return static_cast(verticalAlign_); + } + + /** + * @brief Obtains the size of this text. + * + * @return Returns the text size. + * @since 1.0 + * @version 1.0 + */ + Point GetTextSize() const + { + return textSize_; + } + + virtual void ReMeasureTextSize(const Rect& textRect, const Style& style); + + void OnDraw(const Rect& invalidatedArea, + const Rect& viewOrigRect, + const Rect& textRect, + int16_t offsetX, + const Style& style, + uint16_t ellipsisIndex, + OpacityType opaScale); + + /** + * @brief Sets whether to adapt the component width to this text. + * + * @param expand Specifies whether to adapt the component width to this text. The value true indicates + * that the component width will adapt to this text, and false indicates not. + * @since 1.0 + * @version 1.0 + */ + void SetExpandWidth(bool expand) + { + expandWidth_ = expand; + } + + /** + * @brief Checks whether the component width adapts to this text. + * + * @return Returns true if the component width adapts to this text; returns false otherwise. + * @since 1.0 + * @version 1.0 + */ + bool IsExpandWidth() const + { + return expandWidth_; + } + + /** + * @brief Sets whether to adapt the component height to this text. + * + * @param expand Specifies whether to adapt the component height to this text. The value true indicates + * that the component height will adapt to this text, and false indicates not. + * @since 1.0 + * @version 1.0 + */ + void SetExpandHeight(bool expand) + { + expandHeight_ = expand; + } + + /** + * @brief Checks whether the component height adapts to this text. + * + * @return Returns true if the component height adapts to this text; returns false otherwise. + * @since 1.0 + * @version 1.0 + */ + bool IsExpandHeight() const + { + return expandHeight_; + } + + bool IsNeedRefresh() const + { + return needRefresh_; + } + + /** + * @brief Obtains the index of the character from where text will be replaced by ellipses based on + * the text rectangle and style. + * + * @param textRect Indicates the text rectangle. + * @param style Indicates the text style. + * @since 1.0 + * @version 1.0 + */ + uint16_t GetEllipsisIndex(const Rect& textRect, const Style& style); + +protected: + struct TextLine { + uint16_t lineBytes; + uint16_t linePixelWidth; + }; + + /** Maximum number of lines */ + static constexpr uint16_t MAX_LINE_COUNT = 50; + static TextLine textLine_[MAX_LINE_COUNT]; + + static constexpr int16_t TEXT_ELLIPSIS_DOT_NUM = 3; + static constexpr const char* TEXT_ELLIPSIS = "..."; + + virtual uint32_t GetTextStrLen(); + + virtual uint32_t + GetTextLine(uint32_t begin, uint32_t textLen, int16_t width, uint16_t lineNum, uint8_t letterSpace); + + virtual uint16_t GetLetterIndexByPosition(const Rect& textRect, const Style& style, const Point& pos); + + virtual void Draw(const Rect& mask, + const Rect& coords, + const Style& style, + int16_t offsetX, + uint16_t ellipsisIndex, + OpacityType opaScale); + + uint16_t GetLine(int16_t width, uint8_t letterSpace, uint16_t ellipsisIndex, uint32_t& maxLineBytes); + int16_t TextPositionY(const Rect& textRect, int16_t textHeight); + int16_t LineStartPos(const Rect& textRect, uint16_t lineWidth); + + char* text_; + uint8_t fontId_; + uint8_t fontSize_; // Only the vector font library has a valid value. + Point textSize_; + bool needRefresh_ : 1; + bool expandWidth_ : 1; + bool expandHeight_ : 1; + uint8_t direct_ : 5; // UITextLanguageDirect + +private: + uint8_t horizontalAlign_ : 4; // UITextLanguageAlignment + uint8_t verticalAlign_ : 4; // UITextLanguageAlignment +}; +} // namespace OHOS +#endif // GRAPHIC_LITE_TEXT_H \ No newline at end of file diff --git a/interfaces/kits/components/abstract_adapter.h b/interfaces/kits/components/abstract_adapter.h new file mode 100755 index 0000000..ef79a0c --- /dev/null +++ b/interfaces/kits/components/abstract_adapter.h @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +/** + * @addtogroup UI_Components + * @{ + * + * @brief Defines UI components such as buttons, texts, images, lists, and progress bars. + * + * @since 1.0 + * @version 1.0 + */ + +/** + * @file abstract_adapter.h + * + * @brief Defines the base class for adapters. + * + * @since 1.0 + * @version 1.0 + */ + +#ifndef GRAPHIC_LITE_ABSTRACT_ADAPTER_H +#define GRAPHIC_LITE_ABSTRACT_ADAPTER_H + +#include "components/ui_view.h" + +namespace OHOS { +/** + * @brief Defines the base class for adapters. You can derive AbstractAdapter based on actual requirements + * and use the GetView() and GetCount() functions to implement adapters of different data types. + * For details, see {@link TextAdapter}. + * @since 1.0 + * @version 1.0 + */ +class AbstractAdapter : public HeapBase { +public: + /** + * @brief A constructor used to create an AbstractAdapter instance. + * @since 1.0 + * @version 1.0 + */ + AbstractAdapter() {} + + /** + * @brief A destructor used to delete the AbstractAdapter instance. + * @since 1.0 + * @version 1.0 + */ + virtual ~AbstractAdapter() {} + + /** + * @brief Obtains the number of adapter data items. + * + * @return Returns the number of adapter data items. + * @since 1.0 + * @version 1.0 + */ + virtual uint16_t GetCount() = 0; + + /** + * @brief Obtains a UIView instance to convert adapter data into another UIView instance. + * + * @param inView Indicates the pointer to the reusable instance. If this parameter is not NULL, a reusable + * UIView instance is available. In this case, this function does not need to create a new + * UIView instance, just reusing the instance specified by inView to update the + * inView data. + * If this parameter is NULL, there is no reusable UIView instance. In this case, this + * function needs to create a new UIView instance. + * + * @param index Indicates the adapter data index. + * + * @return UIView Returns the pointer to the UIView instance constructed by the adapter. + * @since 1.0 + * @version 1.0 + */ + virtual UIView* GetView(UIView* inView, int16_t index) = 0; + + virtual void DeleteView(UIView*& view){}; + +protected: + static const uint16_t DEFAULT_WIDTH = 200; + static const uint16_t DEFAULT_HEIGHT = 50; +}; +} // namespace OHOS +#endif // GRAPHIC_LITE_ABSTRACT_ADAPTER_H diff --git a/interfaces/kits/components/root_view.h b/interfaces/kits/components/root_view.h new file mode 100755 index 0000000..0be0102 --- /dev/null +++ b/interfaces/kits/components/root_view.h @@ -0,0 +1,305 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +/** + * @addtogroup UI_Components + * @{ + * + * @brief Defines UI components such as buttons, texts, images, lists, and progress bars. + * + * @since 1.0 + * @version 1.0 + */ + +/** + * @file root_view.h + * + * @brief Manages a root view. + * + * A root view is the view containing its child views. It represents the root node in a tree structure and is + * the parent to all the children. + * + * @since 1.0 + * @version 1.0 + */ + +#ifndef GRAPHIC_LITE_ROOT_VIEW_H +#define GRAPHIC_LITE_ROOT_VIEW_H + +#include +#if defined __linux__ || defined __LITEOS__ || defined __APPLE__ +#include +#endif + +#include "components/ui_view_group.h" +#include "events/key_event.h" +#include "events/virtual_device_event.h" +#include "vector.h" +#include "list.h" + +namespace OHOS { +#if ENABLE_WINDOW +class Window; +class WindowImpl; +#endif + +/** + * @brief Defines the functions related to a root view which contains its child views and represents + * the root node in a tree structure. + * + * @since 1.0 + * @version 1.0 + */ +class RootView : public UIViewGroup { +public: + /** + * @brief Obtains a singleton RootView instance. + * + * @return Returns the singleton RootView instance. + * @since 1.0 + * @version 1.0 + */ + static RootView* GetInstance() + { + static RootView instance; + return &instance; + } + +#if ENABLE_WINDOW + /** + * @brief Obtains a RootView instance bound to a window. + * + * @return Returns the RootView instance. + * @since 1.0 + * @version 1.0 + */ + static RootView* GetWindowRootView() + { + return new RootView; + } + + /** + * @brief Destroys the RootView bound to a window. + * + * @param rootView Indicates the pointer to the RootView to destroy. + * @return Returns true if the operation is successful; returns false otherwise. + * @since 1.0 + * @version 1.0 + */ + static bool DestoryWindowRootView(RootView* rootView) + { + if (rootView == RootView::GetInstance()) { + return false; + } + delete rootView; + return true; + } +#endif + + /** + * @brief Represents the listener for monitoring physical key events. + * + * @since 1.0 + * @version 1.0 + */ + class OnKeyActListener : public HeapBase { + public: + /** + * @brief Responds to a physical key event. + * + * @param view Indicates the view displayed upon a physical key event. + * @param event Indicates the physical key event to respond to. + * @return Returns true if the view is normally displayed upon a physical key + * event; returns false otherwise. + * @since 1.0 + * @version 1.0 + */ + virtual bool OnKeyAct(UIView& view, const KeyEvent& event) = 0; + }; + + /** + * @brief Obtains the view type. + * + * @return Returns UI_ROOT_VIEW, as defined in {@link UIViewType}. + * @since 1.0 + * @version 1.0 + */ + UIViewType GetViewType() const override + { + return UI_ROOT_VIEW; + } + + /** + * @brief Executes a physical key event. + * + * @param event Indicates the physical key event to execute. + * @since 1.0 + * @version 1.0 + */ + virtual void OnKeyEvent(const KeyEvent& event) + { + if (onKeyActListener_ != nullptr) { + onKeyActListener_->OnKeyAct(*this, event); + } + } + + /** + * @brief Sets the listener that contains a callback to be invoked upon a physical key event. + * + * @param onKeyActListener Indicates the pointer to the listener to set. + * @since 1.0 + * @version 1.0 + */ + void SetOnKeyActListener(OnKeyActListener* onKeyActListener) + { + onKeyActListener_ = onKeyActListener; + } + + /** + * @brief Clears the listener for monitoring physical key events. + * + * @since 1.0 + * @version 1.0 + */ + void ClearOnKeyActListener() + { + onKeyActListener_ = nullptr; + } + + /** + * @brief Listens for the input events triggered by a virtual device other than + * human touching or physical pressing. + * + * @since 1.0 + * @version 1.0 + */ + class OnVirtualDeviceEventListener : public HeapBase { + public: + /** + * @brief Responds to an input event triggered by a virtual device. + * + * @param view Indicates the view displayed upon an input event triggered by a virtual device. + * @param event Indicates the input event to respond to. + * @return Returns true if this view is normally displayed upon an input event triggered by a + * virtual device; returns false otherwise. + * @since 1.0 + * @version 1.0 + */ + virtual bool OnVirtualDeviceEvent(UIView& view, VirtualDeviceEvent event) = 0; + }; + + /** + * @brief Executes an input event triggered by a virtual device. + * + * @param event Indicates the input event to respond to. + * @since 1.0 + * @version 1.0 + */ + virtual void OnVirtualDeviceEvent(const VirtualDeviceEvent& event) + { + if (onVirtualEventListener_ != nullptr) { + onVirtualEventListener_->OnVirtualDeviceEvent(*this, event); + } + } + + /** + * @brief Sets a listener for monitoring the input events of a virtual device. + * + * @param onVirtualDeviceEventListener Indicates the pointer to the listener to set. + * @since 1.0 + * @version 1.0 + */ + void SetOnVirtualDeviceEventListener(OnVirtualDeviceEventListener* onVirtualDeviceEventListener) + { + onVirtualEventListener_ = onVirtualDeviceEventListener; + } + + /** + * @brief Clears the listener for monitoring the input events of a virtual device. + * + * @since 1.0 + * @version 1.0 + */ + void ClearOnVirtualDeviceEventListener() + { + onVirtualEventListener_ = nullptr; + } + + /** + * @brief Checks whether the target view is one of the child views of the specified parent view. + * + * @param parentView Indicates the specified parent view. + * @param subView Indicates the target child view. + * @return Returns true if the target view is available; returns false otherwise. + * @since 1.0 + * @version 1.0 + */ + static bool FindSubView(const UIView& parentView, const UIView* subView); + +#if ENABLE_WINDOW + /** + * @brief Obtains the window bound with a RootView. + * + * @return Returns the window. + * @since 1.0 + * @version 1.0 + */ + Window* GetBoundWindow() const; +#endif + +private: + friend class RenderManager; + friend class UIViewGroup; + friend class UIView; +#if ENABLE_WINDOW + friend class WindowImpl; +#endif + + RootView(); + + ~RootView() {} + + inline bool IntersectScreenRect(Rect& rect); + void AddInvalidateRectWithLock(Rect& rect, UIView *view); + void AddInvalidateRect(Rect& rect, UIView* view); + void Measure(); + void MeasureView(UIView* view); + void Render(); + void DrawTop(UIView* view, const Rect& rect); + UIView* GetTopUIView(const Rect& rect); +#if LOCAL_RENDER + void RemoveViewFromInvalidMap(UIView *view); + void DrawInvalidMap(const Rect &buffRect); + void OptimizeInvalidView(UIView* curview, UIView* backgroud, List &renderedRects); + void OptimizeInvalidMap(); + + std::map> invalidateMap_; +#else + bool renderFlag_ = false; + Rect invalidRect_; +#endif + OnKeyActListener* onKeyActListener_ {nullptr}; + OnVirtualDeviceEventListener* onVirtualEventListener_ {nullptr}; + bool enableAnimator_ {false}; +#if defined __linux__ || defined __LITEOS__ || defined __APPLE__ + pthread_mutex_t lock_; +#endif + +#if ENABLE_WINDOW + WindowImpl* boundWindow_ {nullptr}; +#endif +}; +} // namespace OHOS +#endif // GRAPHIC_LITE_ROOT_VIEW_H diff --git a/interfaces/kits/components/text_adapter.h b/interfaces/kits/components/text_adapter.h new file mode 100755 index 0000000..cf85cd2 --- /dev/null +++ b/interfaces/kits/components/text_adapter.h @@ -0,0 +1,282 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +/** + * @addtogroup UI_Components + * @{ + * + * @brief Defines UI components such as buttons, texts, images, lists, and progress bars. + * + * @since 1.0 + * @version 1.0 + */ + +/** + * @file text_adapter.h + * + * @brief Defines a text adapter that is used to construct UILabel instances. + * + * @since 1.0 + * @version 1.0 + */ + +#ifndef GRAPHIC_LITE_TEXT_ADAPTER_H +#define GRAPHIC_LITE_TEXT_ADAPTER_H + +#include "components/abstract_adapter.h" +#include "components/ui_label.h" + +namespace OHOS { +/** + * @brief Defines a text formatter. You can inherit this class and implement the Format() function. + * + * @since 1.0 + * @version 1.0 + */ +class TextFormatter : public HeapBase { +public: + /** + * @brief Converts the input integer into a character string for output. + * + * @param value Indicates the input integer. + * @param outText Indicates the pointer to the converted string. + * @param textLen Indicates the length of the string. + * @since 1.0 + * @version 1.0 + */ + virtual bool Format(int16_t value, char* outText, uint16_t textLen); +}; + +/** + * @brief Defines a text adapter, which implements UILabel instance construction and supports text data and continuous + * integer data. + * + * @since 1.0 + * @version 1.0 + */ +class TextAdapter : public AbstractAdapter { +public: + /** + * @brief A constructor used to create a UILabel instance. + * @since 1.0 + * @version 1.0 + */ + TextAdapter(); + + /** + * @brief A destructor used to delete the UILabel instance. + * @since 1.0 + * @version 1.0 + */ + virtual ~TextAdapter(); + + /** + * @brief Obtains a UILabel instance to convert adapter data into another UILabel instance. + * + * @param inView Indicates the pointer to the reusable instance. If this parameter is not NULL, a reusable + * UILabel instance is available. In this case, this function does not need to create a new + * UILabel instance, just resusing the instance specified by inView to update the inView + * data. If this parameter is NULL, there is no resuable UIView instance. In this case, this + * function needs to create a new UILabel instance. + * + * @param index Indicates the adapter data index. + * + * @return Returns the address of the UILabel instance constructed by the adapter. + * @since 1.0 + * @version 1.0 + */ + UIView* GetView(UIView* inView, int16_t index) override; + + /** + * @brief Sets the UILabel adapter data, which is a string linked list. + * + * @param data Indicates the string linked list data. + * @since 1.0 + * @version 1.0 + */ + void SetData(List* data); + + /** + * @brief Sets continuously increasing data. For example, if you need to set data 0, 1, 2, + * 3, 4, use this function to set start to 0 and end to 4. + * + * @param start Indicates the start value of the integer data. + * @param end Indicates the end value of the integer data. + * @since 1.0 + * @version 1.0 + */ + void SetData(int16_t start, int16_t end); + + /** + * @brief Sets font ID. + * + * @param fontId Indicates the font ID. For details, see {@link UITextLanguageFontId}. + * @since 1.0 + * @version 1.0 + */ + void SetFontId(uint8_t fontId) + { + fontId_ = fontId; + if (fontName_ != nullptr) { + UIFree(fontName_); + fontName_ = nullptr; + } + } + + /** + * @brief Obtains font ID. + * + * @return Returns the font ID. For details, see {@link UITextLanguageFontId}. + * @since 1.0 + * @version 1.0 + */ + uint8_t GetFontId() const + { + return fontId_; + } + + /** + * @brief Sets the font. + * + * @param name Indicates the pointer to the font name. + * @param size Indicates the font size to set. + * @since 1.0 + * @version 1.0 + */ + void SetFont(const char* name, uint8_t size); + + /** + * @brief Obtains the UILabel adapter style. + * + * @return Returns the UILabel adapter style. + * @since 1.0 + * @version 1.0 + */ + Style& GetStyle() + { + return style_; + } + + /** + * @brief Obtains the data size of the UILabel adapter. + * + * @return Returns the data size of the UILabel adapter. + * @since 1.0 + * @version 1.0 + */ + virtual uint16_t GetCount() override; + + /** + * @brief Sets the width of UILabel constructed by the adapter. + * + * @return Returns the width of UILabel. + * @since 1.0 + * @version 1.0 + */ + void SetWidth(int16_t width) + { + width_ = width; + } + + /** + * @brief Sets the direction of the UILabel constructed by the adapter. + * + * @param direct Indicates the direction of the UILabel constructed by the adapter. + * @since 1.0 + * @version 1.0 + */ + void SetDirect(UITextLanguageDirect direct) + { + direct_ = direct; + } + + /** + * @brief Sets the height of the UILabel constructed by the adapter. + * + * @return Returns the height of the UILabel constructed by the adapter. + * @since 1.0 + * @version 1.0 + */ + void SetHeight(int16_t height) + { + height_ = height; + } + + /** + * @brief Sets the LineBreakMode attribute of UILabel constructed by the adapter. For details about the + * values of LineBreakMode, see {@link LINE_BREAK_ADAPT}, {@link LINE_BREAK_WRAP}, + * {@link LINE_BREAK_ELLIPSIS}, and {@link LINE_BREAK_MARQUEE}. + * + * @param lineBreakMode Indicates the LineBreakMode of UILabel. + * @since 1.0 + * @version 1.0 + */ + void SetLineBreakMode(const uint8_t lineBreakMode) + { + lineBreakMode_ = lineBreakMode; + } + + /** + * @brief Sets the callback function to be invoked upon a click event. + * + * @param clickListener Indicates the pointer to the callback function. + * @since 1.0 + * @version 1.0 + */ + void SetOnClickListener(UIView::OnClickListener* clickListener) + { + clickListener_ = clickListener; + } + + /** + * @brief Sets the text formatter. + * + * @param formatter Indicates the pointer to the text formatter. For details, see {@link TextFormatter}. + * + * @since 1.0 + * @version 1.0 + */ + void SetTextFormatter(TextFormatter* formatter) + { + formatter_ = formatter; + } + +protected: + virtual UILabel* GetTextView(UIView* inView, int16_t index); + uint8_t dataMode_; + +private: + static constexpr uint8_t DYNAMIC_TEXT_MODE = 0; + static constexpr uint8_t CONTINUOUS_INTEGER_MODE = 3; + static constexpr uint8_t BUF_LEN = 7; + UILabel* GetDynamicText(UIView* inView, int16_t index); + UILabel* GetIntegerText(UIView* inView, int16_t index); + void ClearDynamicText(); + uint8_t fontId_; + char* fontName_; + uint8_t fontSize_; + int16_t width_; + int16_t height_; + UITextLanguageDirect direct_; + uint8_t lineBreakMode_; + int16_t integerTextStart_; + int16_t integerTextEnd_; + Style style_; + List dynamicText_; + UIView::OnClickListener* clickListener_; + TextFormatter* formatter_; +}; +} // namespace OHOS +#endif // GRAPHIC_LITE_TEXT_ADAPTER_H diff --git a/interfaces/kits/components/ui_abstract_clock.h b/interfaces/kits/components/ui_abstract_clock.h new file mode 100755 index 0000000..584de05 --- /dev/null +++ b/interfaces/kits/components/ui_abstract_clock.h @@ -0,0 +1,244 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +/** + * @addtogroup UI_Components + * @{ + * + * @brief Defines UI components such as buttons, texts, images, lists, and progress bars. + * + * @since 1.0 + * @version 1.0 + */ + +/** + * @file ui_abstract_clock.h + * + * @brief Declares the UIAbstractClock class that provides the functions related to clocks. + * + * @since 1.0 + * @version 1.0 + */ + +#ifndef UI_ABSTRACT_CLOCK_H +#define UI_ABSTRACT_CLOCK_H + +#include "components/ui_view_group.h" + +namespace OHOS { +/** + * @brief An abstract class that contains functions for converting units of time (hour, minute, and second), + * setting and obtaining the time. + * + * @since 1.0 + * @version 1.0 + */ +class UIAbstractClock : public UIViewGroup { +public: + /** + * @brief Represents 60 seconds per minute. + */ + static constexpr uint8_t ONE_MINUTE_IN_SECOND = 60; + + /** + * @brief Represents 60 minutes per hour. + */ + static constexpr uint8_t ONE_HOUR_IN_MINUTE = 60; + + /** + * @brief Represents 24 hours per day. + */ + static constexpr uint8_t ONE_DAY_IN_HOUR = 24; + + /** + * @brief Represents 12 hours every half day. + */ + static constexpr uint8_t HALF_DAY_IN_HOUR = 12; + + /** + * @brief A default constructor used to create a UIAbstractClock instance. + * + * @since 1.0 + * @version 1.0 + */ + UIAbstractClock() : currentHour_(0), currentMinute_(0), currentSecond_(0), mode_(WorkMode::NORMAL) {} + + /** + * @brief A constructor used to create a UIAbstractClock instance with + * time elements (hour, minute and second). + * + * @param hour Indicates the hour. + * @param minute Indicates the minute. + * @param second Indicates the second. + * @since 1.0 + * @version 1.0 + */ + UIAbstractClock(uint8_t hour, uint8_t minute, uint8_t second) + : currentHour_(hour), currentMinute_(minute), currentSecond_(second) + { + } + + /** + * @brief A destructor used to delete the UIAbstractClock instance. + * + * @since 1.0 + * @version 1.0 + */ + virtual ~UIAbstractClock() {} + + /** + * @brief Obtains the view type. + * + * @return Returns UI_ABSTRACT_CLOCK, as defined in {@link UIViewType}. + * @since 1.0 + * @version 1.0 + */ + UIViewType GetViewType() const override + { + return UI_ABSTRACT_CLOCK; + } + + /** + * @brief Sets the time in 24-hour format. + * + * @param hour Indicates the hour to set, within [0, 23] after the modulo operation. + * @param minute Indicates the minute to set, within [0, 59] after the modulo operation. + * @param second Indicates the second to set, within [0, 59] after the modulo operation. + * @since 1.0 + * @version 1.0 + */ + void SetTime24Hour(uint8_t hour, uint8_t minute, uint8_t second); + + /** + * @brief Sets the time in 12-hour format. + * + * @param hour Indicates the hour to set, within [0, 11] after the modulo operation. + * @param minute Indicates the minute to set, within [0, 59] after the modulo operation. + * @param second Indicates the second to set, within [0, 59] after the modulo operation. + * @param am Specifies whether it is in the morning. true indicates that it is in the morning, + * and false indicates that it is in the afternoon. + * @since 1.0 + * @version 1.0 + */ + void SetTime12Hour(uint8_t hour, uint8_t minute, uint8_t second, bool am); + + /** + * @brief Obtains the current number of hours. + * + * @return Returns the current number of hours. + * @since 1.0 + * @version 1.0 + */ + uint8_t GetCurrentHour() const + { + return currentHour_; + } + + /** + * @brief Obtains the current number of minutes. + * + * @return Returns the current number of minutes. + * @since 1.0 + * @version 1.0 + */ + uint8_t GetCurrentMinute() const + { + return currentMinute_; + } + + /** + * @brief Obtains the current number of seconds. + * + * @return Returns the current number of seconds. + * @since 1.0 + * @version 1.0 + */ + uint8_t GetCurrentSecond() const + { + return currentSecond_; + } + + /** + * @brief Increases the time by one second. + * + * @since 1.0 + * @version 1.0 + */ + void IncOneSecond(); + + /** + * @brief Updates this clock. + * + * @param clockInit Specifies whether it is the first initialization. true indicates it is the first + * initialization, and false indicates the opposite case. + * @since 1.0 + * @version 1.0 + */ + virtual void UpdateClock(bool clockInit); + + /** + * @brief Enumerates the working modes of this clock. + */ + enum WorkMode { + /** Always on (drawing not updated) */ + ALWAYS_ON, + /** Normal (drawing updated with the time change) */ + NORMAL, + }; + + /** + * @brief Sets the working mode for this clock. + * + * @param newMode Indicates the working mode to set. For details, see {@link WorkMode}. + * @since 1.0 + * @version 1.0 + */ + virtual void SetWorkMode(WorkMode newMode); + + /** + * @brief Obtains the working mode of this clock. + * + * @return Returns the working mode, as defined in {@link WorkMode}. + * @since 1.0 + * @version 1.0 + */ + virtual WorkMode GetWorkMode() const + { + return mode_; + } + +protected: + /** + * @brief Represents the current number of hours. + */ + uint8_t currentHour_; + + /** + * @brief Represents the current number of minutes. + */ + uint8_t currentMinute_; + + /** + * @brief Represents the current number of seconds. + */ + uint8_t currentSecond_; + + /** + * @brief Represents the current working mode of this clock. + */ + WorkMode mode_; +}; +} // namespace OHOS +#endif // UI_ABSTRACT_CLOCK_H diff --git a/interfaces/kits/components/ui_abstract_progress.h b/interfaces/kits/components/ui_abstract_progress.h new file mode 100755 index 0000000..56ad9d4 --- /dev/null +++ b/interfaces/kits/components/ui_abstract_progress.h @@ -0,0 +1,333 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +/** + * @addtogroup UI_Components + * @{ + * + * @brief Defines UI components such as buttons, texts, images, lists, and progress bars. + * + * @since 1.0 + * @version 1.0 + */ + +/** + * @file ui_abstract_progress.h + * + * @brief Defines the base class attributes and common functions of a progress bar. + * + * @since 1.0 + * @version 1.0 + */ + +#ifndef GRAPHIC_LITE_UI_ABSTRACT_PROGRESS_H +#define GRAPHIC_LITE_UI_ABSTRACT_PROGRESS_H + +#include "common/image.h" +#include "components/ui_view.h" + +namespace OHOS { +/** + * @brief Represents the abstract base class which provides functions related to the progress bar. + * + * @see UIView + * @since 1.0 + * @version 1.0 + */ +class UIAbstractProgress : public UIView { +public: + /** + * @brief A constructor used to create a UIAbstractProgress instance. + * + * @since 1.0 + * @version 1.0 + */ + UIAbstractProgress(); + + /** + * @brief A destructor used to delete the UIAbstractProgress instance. + * + * @since 1.0 + * @version 1.0 + */ + virtual ~UIAbstractProgress(); + + /** + * @brief Obtains the component type. + * + * @return Returns the component type, as defined in {@link UIViewType}. + * @since 1.0 + * @version 1.0 + */ + UIViewType GetViewType() const override + { + return UI_ABSTRACT_PROGRESS; + } + + /** + * @brief Sets whether the background of the progress bar is visible. + * + * @param enable Specifies whether the background of the progress bar is visible. true (the default value) + * indicates that the background is visible, and false indicates the opposite case. + * @since 1.0 + * @version 1.0 + */ + void EnableBackground(bool enable) + { + enableBackground_ = enable; + } + + /** + * @brief Sets the current value for this progress bar. + * + * @param value Indicates the current value of this progress bar, within [rangeMin, rangeMax] specified by + * {@link SetRange}. If the value is less than rangeMin, rangeMin is used; + * if the value is greater than rangeMax, rangeMax is used. + * @see SetRange | GetValue + * @since 1.0 + * @version 1.0 + */ + void SetValue(int32_t value); + + /** + * @brief Obtains the current value of this progress bar. + * + * @return Returns the current value of this progress bar. + * @see SetValue + * @since 1.0 + * @version 1.0 + */ + int32_t GetValue() const + { + return curValue_; + } + + /** + * @brief Sets the range for this progress bar. + * + * rangeMin and rangeMax can be any value represented by int32_t. + * rangeMax must be greater than or equal to rangeMin. + * Otherwise, the setting does not take effect and the original value is used. + * + * @param rangeMax Indicates the maximum value of this progress bar. The default value is 100. + * @param rangeMin Indicates the minimum value of this progress bar. The default value is 0. + * @see GetRangeMin | GetRangeMax + * @since 1.0 + * @version 1.0 + */ + void SetRange(int32_t rangeMax, int32_t rangeMin); + + /** + * @brief Obtains the minimum value of this progress bar. + * + * @return Returns the minimum value of this progress bar. + * @see SetRange | GetRangeMax + * @since 1.0 + * @version 1.0 + */ + int32_t GetRangeMin() const + { + return rangeMin_; + } + + /** + * @brief Obtains the maximum value of this progress bar. + * + * @return Returns the maximum value of this progress bar. + * @see SetRange | GetRangeMin + * @since 1.0 + * @version 1.0 + */ + int32_t GetRangeMax() const + { + return rangeMax_; + } + + /** + * @brief Sets the image for this progress bar. + * + * The size of the image must be the same as that of the progress bar to ensure a normal display. + * If the value of any input parameter is nullptr, image filling is canceled. + * Instead, color filling will be adopted. + * + * @param foregroundImage Indicates the foreground image of the progress bar. The default value is nullptr. + * @param backgroundImage Indicates the background image of the progress bar. The default value is nullptr. + * @since 1.0 + * @version 1.0 + */ + void SetImage(const char* foregroundImage, const char* backgroundImage = nullptr); + + /** + * @brief Sets the image as a pixel map for this progress bar. + * + * The size of the image must be the same as that of the progress bar to ensure a normal display. + * If the value of any input parameter is nullptr, image filling is canceled. + * Instead, color filling will be adopted. + * + * @param foregroundImage Indicates the foreground image of the progress bar. The default value is nullptr. + * @param backgroundImage Indicates the background image of the progress bar. The default value is nullptr. + * @since 1.0 + * @version 1.0 + */ + void SetImage(const ImageInfo* foregroundImage, const ImageInfo* backgroundImage = nullptr); + + /** + * @brief Sets the step for this progress bar. + * + * The step is used to control the update frequency of the progress bar. When the value change exceeds the step, + * the progress bar is redrawn. \n + * For example, when the step is set to 10 and the current progress value is 5, the progress bar will not be + * redrawn if the progress value becomes 14, but will be redrawn if the progress value becomes 15. \n + * In addition, when its current value changes to be the maximum or minimum value, + * the progress bar is redrawn regardless of the step you set. \n + * + * @param step Indicates the step to set. The default value is 1. + * @see GetStep + * @since 1.0 + * @version 1.0 + */ + void SetStep(uint32_t step) + { + step_ = step; + } + + /** + * @brief Obtains the current step of this progress bar. + * + * @return Returns the current step. + * @see SetStep + * @since 1.0 + * @version 1.0 + */ + uint32_t GetStep() const + { + return step_; + } + + /** + * @brief Sets the background style for this progress bar. + * + * @param style Indicates the background style of the progress bar. For details, see {@link Style}. + * @see SetForegroundStyle | GetBackgroundStyle + * @since 1.0 + * @version 1.0 + */ + void SetBackgroundStyle(const Style& style); + + /** + * @brief Sets a background style for this progress bar. + * + * @param key Indicates the key of the style to set. + * @param value Indicates the value matching the key. + * @since 1.0 + * @version 1.0 + */ + void SetBackgroundStyle(uint8_t key, int64_t value); + + /** + * @brief Obtains the background style of this progress bar. + * + * @return Returns the background style. + * @See SetBackgroundStyle + * @since 1.0 + * @version 1.0 + */ + const Style& GetBackgroundStyle() const; + + /** + * @brief Obtains the value of a background style of this progress bar. + * + * @param key Indicates the key of the style. + * @return Returns the value of the style. + * @since 1.0 + * @version 1.0 + */ + int64_t GetBackgroundStyle(uint8_t key) const; + + /** + * @brief Sets the foreground style for this progress bar. + * + * @param style Indicates the foreground style of this progress bar. For details, see {@link Style}. + * @see SetBackgroundStyle | GetForegroundStyle + * @since 1.0 + * @version 1.0 + */ + void SetForegroundStyle(const Style& style); + + /** + * @brief Sets a foreground style for this progress bar. + * + * @param key Indicates the key of the style to set. + * @param value Indicates the value matching the key. + * @since 1.0 + * @version 1.0 + */ + void SetForegroundStyle(uint8_t key, int64_t value); + + /** + * @brief Obtains the foreground style of this progress bar. + * + * @return Returns the foreground style. + * @See SetForegroundStyle + * @since 1.0 + * @version 1.0 + */ + const Style& GetForegroundStyle() const; + + /** + * @brief Obtains the value of a foreground style of this progress bar. + * + * @param key Indicates the key of the style. + * @return Returns the value of the style. + * @since 1.0 + * @version 1.0 + */ + int64_t GetForegroundStyle(uint8_t key) const; + + /** + * @brief Sets the type of caps on the background and foreground of the progress bar. + * + * @param cap Indicates the cap type. For details, see {@link CapType}. + * @since 1.0 + * @version 1.0 + */ + void SetCapType(CapType cap) + { + SetBackgroundStyle(STYLE_LINE_CAP, cap); + SetForegroundStyle(STYLE_LINE_CAP, cap); + } + +protected: + static constexpr uint16_t MAX_PERCENT_VALUE = 100; + static constexpr uint16_t MIN_PERCENT_VALUE = 0; + + uint32_t GetRangeSize() const; + int16_t GetCurrentPos(int16_t distance) const; + virtual bool InitImage(); + bool enableBackground_ : 1; + bool backgroundStyleAllocFlag_ : 1; + bool foregroundStyleAllocFlag_ : 1; + Style* backgroundStyle_; + Style* foregroundStyle_; + Image* backgroundImage_; + Image* foregroundImage_; + int32_t rangeMax_; + int32_t rangeMin_; + int32_t curValue_; + uint32_t step_; + int32_t lastValue_; +}; +} // namespace OHOS +#endif // GRAPHIC_LITE_UI_ABSTRACT_PROGRESS_H diff --git a/interfaces/kits/components/ui_abstract_scroll.h b/interfaces/kits/components/ui_abstract_scroll.h new file mode 100755 index 0000000..2ceb837 --- /dev/null +++ b/interfaces/kits/components/ui_abstract_scroll.h @@ -0,0 +1,356 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +/** + * @addtogroup UI_Components + * @{ + * + * @brief Defines UI components such as buttons, texts, images, lists, and progress bars. + * + * @since 1.0 + * @version 1.0 + */ + +/** + * @file ui_abstract_scroll.h + * + * @brief Declares the base class used to define the attributes of a scroll. The UIList, UIScrollView, and + * UISwipeView inherit from this class. + * + * @since 1.0 + * @version 1.0 + */ + +#ifndef GRAPHIC_LITE_UI_ABSTRACT_SCROLL_H +#define GRAPHIC_LITE_UI_ABSTRACT_SCROLL_H + +#include "animator/animator.h" +#include "animator/easing_equation.h" +#include "components/ui_view_group.h" + +namespace OHOS { +/** + * @brief Defines the attributes of a scroll, including the scroll direction, blank size of a scroll view, velocity and + * effects of a scroll animation. + * + * @since 1.0 + * @version 1.0 + */ +class UIAbstractScroll : public UIViewGroup { +public: + /** + * @brief A constructor used to create a UIAbstractScroll instance. + * + * @since 1.0 + * @version 1.0 + */ + UIAbstractScroll(); + + /** + * @brief A destructor used to delete the UIAbstractScroll instance. + * + * @since 1.0 + * @version 1.0 + */ + virtual ~UIAbstractScroll(); + + /** + * @brief Obtains the view type. + * @return Returns the view type, as defined in {@link UIViewType}. + * @since 1.0 + * @version 1.0 + */ + UIViewType GetViewType() const override + { + return UI_ABSTRACT_SCROLL; + } + + /** + * @brief Sets the blank size for this scroll view. + * + * + * @param value Indicates the blank size to set. The default value is 0. Taking a vertical scroll as an + * example, the value 0 indicates that the head node can only scroll downwards the top of the + * view and the tail node scroll upwards the bottom; the value 10 indicates that the head node + * can continue scrolling down by 10 pixels after it reaches the top of the view. + * @since 1.0 + * @version 1.0 + */ + void SetScrollBlankSize(uint16_t size) + { + scrollBlankSize_ = size; + } + + /** + * @brief Sets the maximum scroll distance after a finger lifts the screen. + * + * @param distance Indicates the maximum scroll distance to set. The default value is 0, indicating that the + * scroll distance is not limited. + * @since 1.0 + * @version 1.0 + */ + void SetMaxScrollDistance(uint16_t distance) + { + maxScrollDistance_ = distance; + } + + /** + * @brief Sets the rebound size, which is the distance a knob moves after being released when it reaches the end of + * a scrollbar. + * + * @param size Indicates the rebound size to set. + * @since 1.0 + * @version 1.0 + */ + void SetReboundSize(uint16_t size) + { + reboundSize_ = size; + } + + /** + * @brief Obtains the maximum scroll distance after a finger lifts the screen. + * + * @return Returns the maximum scroll distance. The default value is 0, indicating that the scroll distance + * is not limited. + * @since 1.0 + * @version 1.0 + */ + uint16_t GetMaxScrollDistance() const + { + return maxScrollDistance_; + } + + /** + * @brief Sets the easing function that specifies a scroll animation after a finger lifts the screen. + * + * @param func Indicates the easing function to set. The default function is {@link EasingEquation::CubicEaseOut}. + * For details, see {@link EasingEquation}. + * @since 1.0 + * @version 1.0 + */ + void SetDragFunc(EasingFunc func) + { + easingFunc_ = func; + } + + /** + * @brief Sets whether to continue scrolling after a finger lifts the screen. + * + * @param throwDrag Specifies whether to continue scrolling after a finger lifts the screen. true indicates + * the scroll continues, and false indicates the scroll stops immediately after a finger + * lifts. + * @since 1.0 + * @version 1.0 + */ + void SetThrowDrag(bool throwDrag) + { + throwDrag_ = throwDrag; + } + + /** + * @brief Moves the position of all child views. + * + * @param offsetX Indicates the offset distance by which a child view is moved on the x-axis. + * @param offsetY Indicates the offset distance by which a child view is moved on the y-axis. + * @since 1.0 + * @version 1.0 + */ + void MoveChildByOffset(int16_t offsetX, int16_t offsetY) override; + + /** + * @brief Sets the drag acceleration. + * + * @param value Indicates the drag acceleration to set. The default value is 10. A larger drag acceleration + * indicates a higher inertial scroll velocity. + * @since 1.0 + * @version 1.0 + */ + void SetDragACCLevel(uint16_t value) + { + if (value != 0) { + dragAccCoefficient_ = value; + } + } + + /** + * @brief Obtains the drag acceleration. + * + * @return Returns the drag acceleration. + * @since 1.0 + * @version 1.0 + */ + uint8_t GetDragACCLevel() const + { + return dragAccCoefficient_; + } + + /** + * @brief Sets the compensation distance after a finger lifts the screen. + * + * @param value Indicates the compensation distance to set. The default value is 0. + * @since 1.0 + * @version 1.0 + */ + void SetSwipeACCLevel(uint16_t value) + { + swipeAccCoefficient_ = value; + } + + /** + * @brief Obtains the compensation distance after a finger lifts the screen. + * + * @return Returns the compensation distance. + * @since 1.0 + * @version 1.0 + */ + uint8_t GetSwipeACCLevel() const + { + return swipeAccCoefficient_; + } + +#if ENABLE_ROTATE_INPUT + /** + * @brief תϵ + * + * @return תϵ + * @since 5.0 + * @version 3.0 + */ + int8_t GetRotateFactor() const + { + return rotateFactor_; + } + + /** + * @brief תϵ + * + * @param factor תϵת¼תתϵij˻Ϊʵʻֵ + * @since 5.0 + * @version 3.0 + */ + void SetRotateFactor(int8_t factor) + { + rotateFactor_ = factor; + } +#endif + + static constexpr uint8_t HORIZONTAL = 0; + static constexpr uint8_t VERTICAL = 1; + +protected: + static constexpr uint8_t HORIZONTAL_AND_VERTICAL = 2; + /* calculate drag throw distance, last drag distance in one tick * DRAG_DISTANCE_COEFFICIENT */ + static constexpr uint8_t DRAG_DISTANCE_COEFFICIENT = 5; + /* calculate drag throw times, drag distance / DRAG_TIMES_COEFFICIENT */ + static constexpr uint8_t DRAG_TIMES_COEFFICIENT = 18; + /* the minimum duration of the swipe animator */ + static constexpr uint8_t MIN_DRAG_TIMES = 5; + /* acceleration calculation coefficient */ + static constexpr uint8_t DRAG_ACC_FACTOR = 10; + /* the maximum number of historical drag data */ + static constexpr uint8_t MAX_DELTA_Y_SIZE = 3; + + class ListAnimatorCallback : public AnimatorCallback { + public: + ListAnimatorCallback() + : curtTime_(0), + dragTimes_(0), + startValueX_(0), + endValueX_(0), + previousValueX_(0), + startValueY_(0), + endValueY_(0), + previousValueY_(0) + { + } + + virtual ~ListAnimatorCallback() {} + + void SetDragTimes(uint16_t times) + { + dragTimes_ = times; + } + + void SetDragStartValue(int16_t startValueX, int16_t startValueY) + { + startValueX_ = startValueX; + previousValueX_ = startValueX; + startValueY_ = startValueY; + previousValueY_ = startValueY; + } + + void SetDragEndValue(int16_t endValueX, int16_t endValueY) + { + endValueX_ = endValueX; + endValueY_ = endValueY; + } + + void RsetCallback() + { + curtTime_ = 0; + dragTimes_ = 0; + startValueX_ = 0; + endValueX_ = 0; + startValueY_ = 0; + endValueY_ = 0; + } + + virtual void Callback(UIView* view) override; + + uint16_t curtTime_; + uint16_t dragTimes_; + int16_t startValueX_; + int16_t endValueX_; + int16_t previousValueX_; + int16_t startValueY_; + int16_t endValueY_; + int16_t previousValueY_; + }; + + bool DragThrowAnimator(Point currentPos, Point lastPos); + virtual void StopAnimator(); + virtual bool DragXInner(int16_t distance) = 0; + virtual bool DragYInner(int16_t distance) = 0; + void RefreshDeltaY(int16_t distance) + { + lastDeltaY_[deltaYIndex_ % MAX_DELTA_Y_SIZE] = distance; + deltaYIndex_++; + } + + void CalculateDragDistance(Point currentPos, Point lastPos, int16_t& dragDistanceX, int16_t& dragDistanceY); + void StartAnimator(int16_t dragDistanceX, int16_t dragDistanceY); + virtual void CalculateReboundDistance(int16_t& dragDistanceX, int16_t& dragDistanceY) {}; + int16_t GetMaxDeltaY() const; + + uint16_t scrollBlankSize_; + uint16_t reboundSize_; + uint16_t maxScrollDistance_; + int16_t lastDeltaY_[MAX_DELTA_Y_SIZE]; + uint8_t dragAccCoefficient_; + uint8_t swipeAccCoefficient_; + uint8_t direction_ : 2; + uint8_t deltaYIndex_ : 2; + uint8_t reserve_ : 4; + bool throwDrag_; + EasingFunc easingFunc_; + ListAnimatorCallback animatorCallback_; + Animator scrollAnimator_; +#if ENABLE_ROTATE_INPUT + int8_t rotateFactor_; + int8_t rotateThreshold_; +#endif +}; +} // namespace OHOS +#endif // GRAPHIC_LITE_UI_ABSTRACT_LIST_VIEW_H diff --git a/interfaces/kits/components/ui_analog_clock.h b/interfaces/kits/components/ui_analog_clock.h new file mode 100755 index 0000000..9d71482 --- /dev/null +++ b/interfaces/kits/components/ui_analog_clock.h @@ -0,0 +1,374 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +/** + * @addtogroup UI_Components + * @{ + * + * @brief Defines UI components such as buttons, texts, images, lists, and progress bars. + * + * @since 1.0 + * @version 1.0 + */ + +/** + * @file ui_analog_clock.h + * + * @brief Declares an analog clock. + * + * @since 1.0 + * @version 1.0 + */ + +#ifndef UI_ANALOG_CLOCK_H +#define UI_ANALOG_CLOCK_H + +#include "components/ui_abstract_clock.h" + +namespace OHOS { +class UIImageView; +/** + * @brief Provides the functions related to an analog clock. + * + * @see UIAbstractClock + * @since 1.0 + * @version 1.0 + */ +class UIAnalogClock : public UIAbstractClock { +public: + /** + * @brief A default constructor used to create a UIAnalogClock instance. + * + * @since 1.0 + * @version 1.0 + */ + UIAnalogClock(); + + /** + * @brief A destructor used to delete the UIAnalogClock instance. + * + * @since 1.0 + * @version 1.0 + */ + virtual ~UIAnalogClock() {} + + /** + * @brief Enumerates the clock hand types. + */ + enum class HandType { + /** Hour hand */ + HOUR_HAND, + /** Minute hand */ + MINUTE_HAND, + /** Second hand */ + SECOND_HAND, + }; + + /** + * @brief Enumerates the drawing types of a clock hand. + */ + enum class DrawType { + /** Using a line to draw a clock hand */ + DRAW_LINE, + /** Using an image to draw a clock hand */ + DRAW_IMAGE + }; + + /** + * @brief Defines the basic attributes of the analog clock hands. This is an inner class of UIAbstractClock. + * + * @since 1.0 + * @version 1.0 + */ + class Hand : public HeapBase { + public: + /** + * @brief A default constructor used to create a Hand instance. + * + * @since 1.0 + * @version 1.0 + */ + Hand() + : center_{0, 0}, + initAngle_(0), + preAngle_(0), + nextAngle_(0), + position_{0, 0}, + imageInfo_{{0, 0, 0}}, + color_{{0, 0, 0}}, + width_(0), + height_(0), + opacity_(0), + drawtype_(DrawType::DRAW_IMAGE) + { + } + + /** + * @brief A destructor used to delete the Hand instance. + * + * @since 1.0 + * @version 1.0 + */ + virtual ~Hand() {} + + /** + * @brief Represents the rotation center of a clock hand. + */ + Point center_; + + /** + * @brief Represents the initial clockwise rotation angle of a clock hand. The default value is 0, + * indicating that the hand direction is vertically upward. + */ + uint16_t initAngle_; + + /** + * @brief Represents the latest rotation angle of this clock hand. + */ + uint16_t preAngle_; + + /** + * @brief Represents the next rotation angle of this clock hand. + */ + uint16_t nextAngle_; + + /** + * @brief Represents the position of a hand on this analog clock. + */ + Point position_; + + /** + * @brief Represents the image information of this clock hand. + */ + ImageInfo imageInfo_; + + /** + * @brief Represents the information about the rotation and translation of this clock hand. + */ + TransformMap trans_; + + /** + * @brief Represents the new rectangle area after the rotation and translation. + */ + Rect target_; + + /** + * @brief Represents the color of this clock hand. + */ + ColorType color_; + + /** + * @brief Represents the width of this clock hand. + */ + uint16_t width_; + + /** + * @brief Represents the height of this clock hand. + */ + uint16_t height_; + + /** + * @brief Represents the opacity of this clock hand. + */ + OpacityType opacity_; + + /** + * @brief Represents the drawing type of this clock hand. + */ + DrawType drawtype_; + }; + + /** + * @brief Obtains the view type. + * + * @return Returns UI_ANALOG_CLOCK, as defined in {@link UIViewType}. + * @since 1.0 + * @version 1.0 + */ + UIViewType GetViewType() const override + { + return UI_ANALOG_CLOCK; + } + + /** + * @brief Sets the image used to draw a clock hand. + * + * @param type Indicates the clock hand type, as enumerated in {@link HandType}. + * @param img Indicates the image to set. + * @param position Indicates the start position of this image. + * @param center Indicates the rotation center of this clock hand. + * @since 1.0 + * @version 1.0 + */ + void SetHandImage(HandType type, const UIImageView& img, Point position, Point center); + + /** + * @brief Sets the line used to draw a clock hand. + * + * @param type Indicates the clock hand type, as enumerated in {@link HandType}. + * @param position Indicates the position of the line endpoint close to the rotation center. + * @param center Indicates the rotation center of this clock hand. + * @param color Indicates the color of this line. + * @param width Indicates the width of this line when it is 12 o'clock. + * @param height Indicates the height of this line when it is 12 o'clock. + * @param opacity Indicates the opacity of this line. + * @since 1.0 + * @version 1.0 + */ + void SetHandLine(HandType type, + Point position, + Point center, + ColorType color, + uint16_t width, + uint16_t height, + OpacityType opacity); + + /** + * @brief Obtains the rotation center of a specified clock hand. + * + * @param type Indicates the clock hand type, as enumerated in {@link HandType}. + * @return Returns the rotation center. + * @since 1.0 + * @version 1.0 + */ + Point GetHandRotateCenter(HandType type) const; + + /** + * @brief Obtains the position of a specified clock hand. + * + * @param type Indicates the clock hand type, as enumerated in {@link HandType}. + * @return Returns the position of this specified clock hand. + * @since 1.0 + * @version 1.0 + */ + Point GetHandPosition(HandType type) const; + + /** + * @brief Obtains the initial rotation angle of the specified clock hand. + * + * @param type Indicates the clock hand type, as enumerated in {@link HandType}. + * @return Returns the initial rotation angle of this specified clock hand. + * @since 1.0 + * @version 1.0 + */ + uint16_t GetHandInitAngle(HandType type) const; + + /** + * @brief Obtains the current rotation angle of the specified clock hand. + * + * @param type Indicates the clock hand type, as enumerated in {@link HandType}. + * @return Returns the current rotation angle of this specified clock hand. + * @since 1.0 + * @version 1.0 + */ + uint16_t GetHandCurrentAngle(HandType type) const; + + /** + * @brief Sets the initial time in the 24-hour format. + * + * @param hour Indicates the hour to set. + * @param minute Indicates the minute to set. + * @param second Indicates the second to set. + * @since 1.0 + * @version 1.0 + */ + void SetInitTime24Hour(uint8_t hour, uint8_t minute, uint8_t second); + + /** + * @brief Sets the initial time in the 12-hour format. + * + * @param hour Indicates the hour to set. + * @param minute Indicates the minute to set. + * @param second Indicates the second to set. + * @param am Specifies whether it is in the morning. true indicates that it is in the morning, + * and false indicates that it is in the afternoon. + * @since 1.0 + * @version 1.0 + */ + void SetInitTime12Hour(uint8_t hour, uint8_t minute, uint8_t second, bool am); + + /** + * @brief Draws an analog clock. + * + * @param invalidatedArea Indicates the area to draw. + * @since 1.0 + * @version 1.0 + */ + void OnDraw(const Rect& invalidatedArea) override; + + /** + * @brief Performs the operations needed after the drawing. + * + * @param invalidatedArea Indicates the area to draw. + * @since 1.0 + * @version 1.0 + */ + virtual void OnPostDraw(const Rect& invalidatedArea) override; + + /** + * @brief Sets the position for this analog clock. + * + * @param x Indicates the x-coordinate to set. + * @param y Indicates the y-coordinate to set. + * @since 1.0 + * @version 1.0 + */ + void SetPosition(int16_t x, int16_t y) override; + + /** + * @brief Sets the position and size for this analog clock. + * + * @param x Indicates the x-coordinate to set. + * @param y Indicates the y-coordinate to set. + * @param width Indicates the width to set. + * @param height Indicates the height to set. + * @since 1.0 + * @version 1.0 + */ + void SetPosition(int16_t x, int16_t y, int16_t width, int16_t height) override; + + /** + * @brief Sets the working mode for this analog clock. + * + * @param newMode Indicates the working mode to set. For details, see {@link WorkMode}. + * @since 1.0 + * @version 1.0 + */ + void SetWorkMode(WorkMode newMode) override; + + /** + * @brief Updates the time of this analog clock. + * + * @param clockInit Specifies whether it is the first initialization. true indicates it is the + * first initialization, and false indicates the opposite case. + * @since 1.0 + * @version 1.0 + */ + void UpdateClock(bool clockInit) override; + +private: + Hand hourHand_; + Hand minuteHand_; + Hand secondHand_; + + void DrawHand(const Rect& current, const Rect& invalidatedArea, Hand& hand); + void DrawHandImage(const Rect& current, const Rect& invalidatedArea, Hand& hand); + void DrawHandLine(const Rect& invalidatedArea, Hand& hand); + uint16_t ConvertHandValueToAngle(uint8_t handValue, uint8_t range, uint8_t secondHandValue, uint8_t ratio) const; + uint16_t ConvertHandValueToAngle(uint8_t handValue, uint8_t range) const; + void CalculateRedrawArea(const Rect& current, Hand& hand, bool clockInit); +}; +} // namespace OHOS +#endif // UI_ANALOG_CLOCK_H diff --git a/interfaces/kits/components/ui_arc_label.h b/interfaces/kits/components/ui_arc_label.h new file mode 100755 index 0000000..fd66e0d --- /dev/null +++ b/interfaces/kits/components/ui_arc_label.h @@ -0,0 +1,381 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +/** + * @addtogroup UI_Components + * @{ + * + * @brief Defines UI components such as buttons, texts, images, lists, and progress bars. + * + * @since 1.0 + * @version 1.0 + */ + +/** + * @file ui_arc_label.h + * + * @brief Defines the attributes of an arc label. + * + * The attributes include the center and radius of an arc, angle range, and text orientation. + * + * @since 1.0 + * @version 1.0 + */ + +#ifndef GRAPHIC_LITE_UI_ARC_LABEL_H +#define GRAPHIC_LITE_UI_ARC_LABEL_H + +#include "common/text.h" +#include "components/ui_view.h" + +namespace OHOS { +/** + * @brief Defines functions related to an arc label. + * + * @since 1.0 + * @version 1.0 + */ +class UIArcLabel : public UIView { +public: + /** + * @brief Enumerates text orientations. + */ + enum class TextOrientation : uint8_t { + /** Inside */ + INSIDE, + /** Outside */ + OUTSIDE, + }; + + /** + * @brief A default constructor used to create a UIArcLabel instance. + * + * @since 1.0 + * @version 1.0 + */ + UIArcLabel(); + + /** + * @brief A destructor used to delete the UIArcLabel instance. + * + * @since 1.0 + * @version 1.0 + */ + virtual ~UIArcLabel(); + + /** + * @brief Obtains the view type. + * + * @return Returns UI_ARC_LABEL, as defined in {link UIViewType}. + * @since 1.0 + * @version 1.0 + */ + UIViewType GetViewType() const override + { + return UI_ARC_LABEL; + } + + /** + * @brief Obtains the width of this arc text. + * + * @return Returns the width of this arc text. + * @since 1.0 + * @version 1.0 + */ + int16_t GetWidth() override + { + ReMeasure(); + return UIView::GetWidth(); + } + + /** + * @brief Obtains the height of this arc text. + * + * @return Returns the height of this arc text. + * @since 1.0 + * @version 1.0 + */ + int16_t GetHeight() override + { + ReMeasure(); + return UIView::GetHeight(); + } + + /** + * @brief Sets a style. + * + * @param key Indicates the key of the style to set. + * @param value Indicates the value matching the key. + * @since 1.0 + * @version 1.0 + */ + void SetStyle(uint8_t key, int64_t value) override; + + /** + * @brief Sets the text content for this arc label. + * + * @param text Indicates the pointer to the text content. + * @since 1.0 + * @version 1.0 + */ + void SetText(const char* text); + + /** + * @brief Obtains the text of this arc label. + * + * @return Returns the text. + * @since 1.0 + * @version 1.0 + */ + const char* GetText() const; + + /** + * @brief Sets the alignment mode for this text. + * + * @param horizontalAlign Indicates the horizontal alignment mode to set, + * which can be {@link TEXT_ALIGNMENT_LEFT}, + * {@link TEXT_ALIGNMENT_CENTER}, or {@link TEXT_ALIGNMENT_RIGHT}. + * @since 1.0 + * @version 1.0 + */ + void SetAlign(UITextLanguageAlignment horizontalAlign); + + /** + * @brief Obtains the horizontal alignment mode. + * + * @return Returns the horizontal alignment mode. + * @since 1.0 + * @version 1.0 + */ + UITextLanguageAlignment GetHorAlign(); + + /** + * @brief Obtains the direction of this text. + * + * @return Returns the text direction, as defined in {@link UITextLanguageDirect}. + * @since 1.0 + * @version 1.0 + */ + UITextLanguageDirect GetDirect(); + + /** + * @brief Sets the font ID for this arc label. + * + * @param fontId Indicates the font ID composed of font name and size. + * @since 1.0 + * @version 1.0 + */ + void SetFontId(uint8_t fontId); + + /** + * @brief Obtains the font ID composed of font name and size. + * + * @return Returns the front ID of this arc label. + * @since 1.0 + * @version 1.0 + */ + uint8_t GetFontId(); + + /** + * @brief Sets the font for this arc label. + * + * @param name Indicates the pointer to the font name. + * @param size Indicates the font size to set. + * @since 1.0 + * @version 1.0 + */ + void SetFont(const char* name, uint8_t size); + + /** + * @brief Sets the center position for this arc text. + * + * @param x Indicates the x-coordinate to set. + * @param y Indicates the y-coordinate to set. + * @since 1.0 + * @version 1.0 + */ + void SetArcTextCenter(int16_t x, int16_t y) + { + if ((arcCenter_.x != x) || (arcCenter_.y != y)) { + arcCenter_.x = x; + arcCenter_.y = y; + RefreshArcLabel(); + } + } + + /** + * @brief Obtains the center position of this arc text. + * + * @return Returns the center position of this arc text. + * @since 1.0 + * @version 1.0 + */ + Point GetArcTextCenter() const + { + return arcCenter_; + } + + /** + * @brief Sets the radius for this arc text. + * + * @param radius Indicates the radius to set. + * @since 1.0 + * @version 1.0 + */ + void SetArcTextRadius(uint16_t radius) + { + if (radius_ != radius) { + radius_ = radius; + RefreshArcLabel(); + } + } + + /** + * @brief Obtains the radius of this arc text. + * + * @return Returns the radius of this arc text. + * @since 1.0 + * @version 1.0 + */ + uint16_t GetArcTextRadius() const + { + return radius_; + } + + /** + * @brief Sets the start angle and end angle for this arc text. + * + * The angle in 12 o'clock direction is 0 degrees, and the value increases clockwise. + * The text direction is clockwise when the end angle is greater than the start angle, and the text direction is + * counterclockwise otherwise. + * + * @param startAngle Indicates the start angle to set. + * @param endAngle Indicates the end angle to set. + * @since 1.0 + * @version 1.0 + */ + void SetArcTextAngle(int16_t startAngle, int16_t endAngle) + { + if ((startAngle_ != startAngle) || (endAngle_ != endAngle)) { + startAngle_ = startAngle; + endAngle_ = endAngle; + RefreshArcLabel(); + } + } + + /** + * @brief Obtains the start angle of this arc text. + * + * @return Returns the start angle of this arc text. + * @since 1.0 + * @version 1.0 + */ + int16_t GetArcTextStartAngle() const + { + return startAngle_; + } + + /** + * @brief Obtains the end angle of this arc text. + * + * @return Returns the end angle of this arc text. + * @since 1.0 + * @version 1.0 + */ + int16_t GetArcTextEndAngle() const + { + return endAngle_; + } + + /** + * @brief Sets the orientation for this arc text. + * + * @param orientation Indicates the text orientation to set. + * @since 1.0 + * @version 1.0 + */ + void SetArcTextOrientation(TextOrientation orientation) + { + if (orientation_ != orientation) { + orientation_ = orientation; + RefreshArcLabel(); + } + } + + /** + * @brief Obtains the orientation of this arc text. + * + * @return Returns the orientation of this arc text. + * @since 1.0 + * @version 1.0 + */ + TextOrientation GetArcTextOrientation() const + { + return orientation_; + } + + /** + * @brief Draws an arc text. + * + * @param invalidatedArea Indicates the area to draw. + * @since 1.0 + * @version 1.0 + */ + virtual void OnDraw(const Rect& invalidatedArea) override; + + /** + * @brief Stores the attribute information about this arc text to draw. + */ + struct ArcTextInfo { + uint16_t radius; + float startAngle; + Point arcCenter; + uint32_t lineStart; + uint32_t lineEnd; + UITextLanguageDirect direct; + }; + +protected: + Text* arcLabelText_; + + virtual void InitArcLabelText() + { + if (arcLabelText_ == nullptr) { + arcLabelText_ = new Text(); + if (arcLabelText_ == nullptr) { + GRAPHIC_LOGE("new Text fail"); + return; + } + } + } + void RefreshArcLabel(); + +private: + virtual void ReMeasure() override; + void MeasureArcTextInfo(); + void DrawArcText(const Rect& mask, OpacityType opaScale); + + bool needRefresh_; + Point textSize_; + uint16_t radius_; + int16_t startAngle_; + int16_t endAngle_; + Point arcCenter_; + TextOrientation orientation_; + + ArcTextInfo arcTextInfo_; +}; +} // namespace OHOS +#endif // GRAPHIC_LITE_UI_ARC_LABEL_H diff --git a/interfaces/kits/components/ui_axis.h b/interfaces/kits/components/ui_axis.h new file mode 100755 index 0000000..ae795a0 --- /dev/null +++ b/interfaces/kits/components/ui_axis.h @@ -0,0 +1,314 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +/** + * @addtogroup UI_Components + * @{ + * + * @brief Defines UI components such as buttons, texts, images, lists, and progress bars. + * + * @since 1.0 + * @version 1.0 + */ + +/** + * @file ui_axis.h + * + * @brief Defines the attributes and functions of the x- and y-axises. This class is used in {@link UIChart}. + * + * @since 1.0 + * @version 1.0 + */ + +#ifndef GRAPHIC_LITE_UI_AXIS_H +#define GRAPHIC_LITE_UI_AXIS_H + +#include "components/ui_label.h" +#include "components/ui_view_group.h" + +namespace OHOS { +/** + * @brief Represents the coordinate axis base class, which defines the basic attributes of coordinate axis, + * sets whether a coordinate axis is visible, and sets the number of scales on a coordinate axis. + * This class is used in {@link UIChart}. + * + * @since 1.0 + * @version 1.0 + */ +class UIAxis : public UIViewGroup { +public: + /** + * @brief A constructor used to create a UIAxis instance. + * + * @since 1.0 + * @version 1.0 + */ + UIAxis(); + + /** + * @brief A destructor used to delete the UIAxis instance. + * + * @since 1.0 + * @version 1.0 + */ + virtual ~UIAxis() {} + + /** + * @brief Obtains the view type. + * + * @return Returns the view type. For details, see {@link UIViewType}. + * @since 1.0 + * @version 1.0 + */ + UIViewType GetViewType() const override + { + return UI_AXIS; + } + + /** + * @brief Sets the value range of a coordinate axis. + * + * The maximum value must be greater than the minimum value. Otherwise, the setting fails. + * + * @param min Indicates the minimum value to set. + * @param max Indicates the maximum value to set. + * @return Returns true if the setting is successful; returns false otherwise. + * @since 1.0 + * @version 1.0 + */ + virtual bool SetDataRange(uint16_t min, uint16_t max) = 0; + + /** + * @brief Sets the number of scales on a coordinate axis. + * + * For a bar chart, the number of scales must be the same as that of bars so that each bar + * can be properly displayed between two scales. + * + * @param count Indicates the number of scales to set. The default value is 5. + * @since 1.0 + * @version 1.0 + */ + virtual void SetMarkNum(uint16_t count) = 0; + + void EnableReverse(bool enable) + { + enableReverse_ = enable; + } + + const Point& GetStartPoint() const + { + return start_; + } + + const Point& GetEndPoint() const + { + return end_; + } + + float GetMarkInterval() const + { + return markInterval_; + } + + /** + * @brief Sets the line color of the coordinate axis. + * + * @param color Indicates the line color to set. For details, see {@link ColorType}. + * @since 1.0 + * @version 1.0 + */ + void SetLineColor(const ColorType& color); + + void OnDraw(const Rect& invalidatedArea) override; + + bool OnPreDraw(Rect& invalidatedArea) const override + { + return false; + } + + virtual bool UpdateAxis() = 0; + + /** + * @brief Translates data into pixel coordinates. + * + * This function calculates the relative position of a pixel in the corresponding {@link UIChart} + * based on the value of value and the data range of the coordinate axis. + * + * @param value Indicates the current value. The coordinate value obtained after translation is + * also printed using this parameter. + * @since 1.0 + * @version 1.0 + */ + virtual void TranslateToPixel(int16_t& value) = 0; + + virtual void UpdateAxisPoints() = 0; + +protected: + float maxRange_; + float minRange_; + Point start_; + Point end_; + float markInterval_; + float dataPerMark_; + float dataInterval_; + uint16_t markDataCount_; + bool enableReverse_; + + static constexpr uint8_t AXIS_DEFAULT_MARK_INTERVAL = 5; + static constexpr uint8_t AXIS_DEFAULT_MARK_LENGTH = 1; + + virtual void DrawAxisMark(const Rect& invalidatedArea) = 0; +}; + +/** + * @brief Defines the unique attributes and functions for the x-axis. This class is used in {@link UIChart}. + * + * @see UIAxis + * @since 1.0 + * @version 1.0 + */ +class UIXAxis : public UIAxis { +public: + /** + * @brief A constructor used to create a UIXAxis instance. + * + * @since 1.0 + * @version 1.0 + */ + UIXAxis() {} + + /** + * @brief A destructor used to delete the UIXAxis instance. + * + * @since 1.0 + * @version 1.0 + */ + virtual ~UIXAxis() {} + + bool UpdateAxis() override; + + /** + * @brief Translates data into the x coordinate of a pixel. + * + * This function calculates the position of the corresponding pixel (relative position in the chart) + * based on the value of value and the data range of the x-axis. + * + * @param value Indicates the current value. The x coordinate obtained after translation is also + * printed using this parameter. + * @since 1.0 + * @version 1.0 + */ + void TranslateToPixel(int16_t& value) override; + + /** + * @brief Sets the value range of the X axis. + * + * The maximum value must be greater than the minimum value. Otherwise, the setting fails. + * + * @param min Indicates the minimum value to set. + * @param max Indicates the maximum value to set. + * @return Returns true if the setting is successful; returns false otherwise. + * @since 1.0 + * @version 1.0 + */ + bool SetDataRange(uint16_t min, uint16_t max) override; + + /** + * @brief Sets the number of scales on the x-axis. + * + * For a bar chart, the number of scales must be the same as that of bars so that each bar can be properly + * displayed between two scales. + * + * @param count Indicates the number of scales to set. The default value is 5. + * @since 1.0 + * @version 1.0 + */ + void SetMarkNum(uint16_t count) override; + + void UpdateAxisPoints() override; + +private: + void DrawAxisMark(const Rect& invalidatedArea) override; +}; + +/** + * @brief Defines the unique attributes and functions for the y-axis. This class is used in {@link UIChart}. + * + * @see UIAxis + * @since 1.0 + * @version 1.0 + */ +class UIYAxis : public UIAxis { +public: + /** + * @brief A constructor used to create a UIYAxis instance. + * + * @since 1.0 + * @version 1.0 + */ + UIYAxis() {} + + /** + * @brief A destructor used to delete the UIYAxis instance. + * + * @since 1.0 + * @version 1.0 + */ + virtual ~UIYAxis() {} + + bool UpdateAxis() override; + + /** + * @brief Translates data into the y coordinate of a pixel. + * + * Calculates the position of the corresponding pixel (relative position in the chart) based on the value + * of value and the data range of the Y axis. + * + * @param value Indicates the current value. The y coordinate obtained after translation is also printed + * using this parameter. + * @since 1.0 + * @version 1.0 + */ + void TranslateToPixel(int16_t& value) override; + + /** + * @brief Sets the value range of the y-axis. + * + * The maximum value must be greater than the minimum value. Otherwise, the setting fails. + * + * @param min Indicates the minimum value to set. + * @param max Indicates the maximum value to set. + * @return Returns true if the setting is successful; returns false otherwise. + * @since 1.0 + * @version 1.0 + */ + bool SetDataRange(uint16_t min, uint16_t max) override; + + /** + * @brief Sets the number of scales on the Y axis. + * + * @param count Indicates the number of scales to set. The default value is 5. + * @since 1.0 + * @version 1.0 + */ + void SetMarkNum(uint16_t count) override; + + void UpdateAxisPoints() override; + +private: + void DrawAxisMark(const Rect& invalidatedArea) override; +}; +} // namespace OHOS +#endif // GRAPHIC_LITE_UI_AXIS_H diff --git a/interfaces/kits/components/ui_box_progress.h b/interfaces/kits/components/ui_box_progress.h new file mode 100755 index 0000000..4682835 --- /dev/null +++ b/interfaces/kits/components/ui_box_progress.h @@ -0,0 +1,240 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +/** + * @addtogroup UI_Components + * @{ + * + * @brief Defines UI components such as buttons, texts, images, lists, and progress bars. + * + * @since 1.0 + * @version 1.0 + */ + +/** + * @file ui_box_progress.h + * + * @brief Defines the attributes and common functions of a linear progress bar. + * + * @since 1.0 + * @version 1.0 + */ + +#ifndef GRAPHIC_LITE_UI_BOX_PROGRESS_H +#define GRAPHIC_LITE_UI_BOX_PROGRESS_H + +#include "components/ui_abstract_progress.h" + +namespace OHOS { +/** + * @brief Represents a linear progress bar. + * + * This class is used to set the range and current value to display the linear progress bar + * which can be in multiple directions. + * + * @see UIAbstractProgress + * @since 1.0 + * @version 1.0 + */ +class UIBoxProgress : public UIAbstractProgress { +public: + /** + * @brief Enumerates the directions of the progress bar. + */ + enum class Direction : uint8_t { + /** Filling from left to right */ + DIR_LEFT_TO_RIGHT, + /** Filling from right to left */ + DIR_RIGHT_TO_LEFT, + /** Filling from top to bottom */ + DIR_TOP_TO_BOTTOM, + /** Filling from bottom to top */ + DIR_BOTTOM_TO_TOP, + }; + + /** + * @brief A constructor used to create a UIBoxProgress instance. + * + * @since 1.0 + * @version 1.0 + */ + UIBoxProgress(); + + /** + * @brief A destructor used to delete the UIBoxProgress instance. + * + * @since 1.0 + * @version 1.0 + */ + virtual ~UIBoxProgress() {} + + /** + * @brief Obtains the view type. + * + * @return Returns the view type, as defined in {@link UIViewType}. + * @since 1.0 + * @version 1.0 + */ + UIViewType GetViewType() const override + { + return UI_BOX_PROGRESS; + } + + /** + * @brief Sets the width for the view holding this progress bar. + * + * The width of the view must be greater than or equal to the actual width of the progress bar + * to ensure a normal display. \n + * + * @param width Indicates the width of the view. + * @see SetHeight | SetValidWidth | SetValidHeight + * @since 1.0 + * @version 1.0 + */ + void SetWidth(int16_t width) override + { + UIView::SetWidth(width); + if (!isValidWidthSet_) { + progressWidth_ = width; + } + } + + /** + * @brief Sets the height for this view. + * + * The height of the view must be greater than or equal to the actual height of the progress bar + * to ensure a normal display. \n + * + * @param height Indicates the height to set. + * @see SetWidth | SetValidWidth | SetValidHeight + * @since 1.0 + * @version 1.0 + */ + void SetHeight(int16_t height) override + { + UIView::SetHeight(height); + if (!isValidHeightSet_) { + progressHeight_ = height; + } + } + + /** + * @brief Sets the direction for this progress bar. + * + * @param direction Indicates the direction to set. The default direction is from left to right. + * For details, see {@link Direction}. + * @see GetDirection + * @since 1.0 + * @version 1.0 + */ + void SetDirection(const Direction& direction) + { + direction_ = direction; + } + + /** + * @brief Obtains the direction of this progress bar. + * + * @return Returns the direction of this progress bar, as defined in {@link Direction}. + * @see SetDirection + * @since 1.0 + * @version 1.0 + */ + Direction GetDirection() const + { + return direction_; + } + + /** + * @brief Sets the actual width for this progress bar. + * + * The progress bar is centered in the view after the setting. By default, the width of the progress bar + * is the same as that of the view. \n + * If the width of the progress bar is greater than that of the view, the excess part cannot be displayed. \n + * + * @param width Indicates the actual width of this progress bar. + * @see GetValidWidth + * @since 1.0 + * @version 1.0 + */ + void SetValidWidth(int16_t width) + { + progressWidth_ = width; + isValidWidthSet_ = true; + } + + /** + * @brief Obtains the actual width of this progress bar. + * + * @return Returns the actual width of this progress bar. + * @see SetValidWidth + * @since 1.0 + * @version 1.0 + */ + int16_t GetValidWidth() const + { + return progressWidth_; + } + + /** + * @brief Sets the actual height for this progress bar. + * + * The progress bar is centered in the view after the setting. By default, the height of the progress bar + * is the same as that of the view. \n + * If the height of the progress bar is greater than that of the view, the excess part cannot be displayed. \n + * + * @param height Indicates the actual height to set. + * @see GetValidHeight + * @since 1.0 + * @version 1.0 + */ + void SetValidHeight(int16_t height) + { + progressHeight_ = height; + isValidHeightSet_ = true; + } + + /** + * @brief Obtains the actual height of this progress bar. + * + * @return Returns the actual height of this progress bar. + * @see SetValidHeight + * @since 1.0 + * @version 1.0 + */ + int16_t GetValidHeight() const + { + return progressHeight_; + } + + void OnDraw(const Rect& invalidatedArea) override; + +protected: + void GetBackgroundParam(Point& startPoint, int16_t& width, int16_t& height, uint16_t& radius, const Style& style); + void DrawBackground(const Rect& invalidatedArea); + void DrawForeground(const Rect& invalidatedArea, Rect& coords); + void DrawRoundCap(const Image* image, const Point& imgPos, const Rect& rect, const Rect& invalidatedArea, + uint16_t radius, const Style& style); + void DrawValidRect(const Image* image, const Rect& rect, const Rect& invalidatedArea, const Style& style, + uint16_t radius); + + uint16_t progressWidth_; + uint16_t progressHeight_; + Direction direction_; + bool isValidWidthSet_ : 1; + bool isValidHeightSet_ : 1; +}; +} // namespace OHOS +#endif // GRAPHIC_LITE_UI_BOX_PROGRESS_H diff --git a/interfaces/kits/components/ui_button.h b/interfaces/kits/components/ui_button.h new file mode 100755 index 0000000..f949ebf --- /dev/null +++ b/interfaces/kits/components/ui_button.h @@ -0,0 +1,415 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +/** + * @addtogroup UI_Components + * @{ + * + * @brief Defines UI components such as buttons, texts, images, lists, and progress bars. + * + * @since 1.0 + * @version 1.0 + */ + +/** + * @file ui_button.h + * + * @brief Defines the attributes and common functions of a button. + * + * @since 1.0 + * @version 1.0 + */ + +#ifndef GRAPHIC_LITE_UI_BUTTON_H +#define GRAPHIC_LITE_UI_BUTTON_H + +#include "common/image.h" +#include "components/ui_view.h" + +namespace OHOS { +/** + * @brief Represents a button. + * + * This component responds to the press and release events. + * + * @since 1.0 + * @version 1.0 + */ +class UIButton : public UIView { +public: + /** + * @brief A constructor used to create a UIButton instance. + * + * @since 1.0 + * @version 1.0 + */ + UIButton(); + + /** + * @brief A constructor used to create a UIButton instance based on the button ID. + * + * Buttons sharing the same ID are in the same batch. + * + * @param id Indicates the button ID. + * @since 1.0 + * @version 1.0 + */ + UIButton(const char* id) : UIButton() + { + id_ = id; + } + + /** + * @brief A destructor used to delete the UIButton instance. + * + * @since 1.0 + * @version 1.0 + */ + virtual ~UIButton(); + + /** + * @brief Obtains the component type. + * + * @return Returns the component type, as defined in {@link UIViewType}. + * @since 1.0 + * @version 1.0 + */ + UIViewType GetViewType() const override + { + return UI_BUTTON; + } + + /** + * @fn virtual bool UIButton::OnPreDraw(Rect& invalidatedArea) override + * + * @brief Do something before draw, this function will be invoked mainly to check if this view need + * to cover invalidate area so render manager can decide which layer to draw firstly. + * @param [in] invalidate area. + * @returns True if need cover. + */ + bool OnPreDraw(Rect& invalidatedArea) const override; + + /** + * @fn virtual void UIButton::OnDraw(const Rect& invalidatedArea) override; + * + * @brief Executes the draw action + * + * @param [in] invalidatedArea The rectangle to draw, with coordinates relative to this drawable.. + */ + void OnDraw(const Rect& invalidatedArea) override; + + /** + * @fn virtual void UIButton::OnPressEvent(const PressEvent& event) override; + * + * @brief Executes the press event action + * + * @param [in] event The press event, contain press position. + * + * @return Returns true if the event is consumed; returns false otherwise. + */ + bool OnPressEvent(const PressEvent& event) override; + + /** + * @fn virtual void UIButton::OnReleaseEvent(const ReleaseEvent& event) override; + * + * @brief Executes the press release event action + * + * @param [in] event The press release event. + */ + bool OnReleaseEvent(const ReleaseEvent& event) override; + + /** + * @fn virtual void UIButton::OnCancelEvent(const CancelEvent& event) override; + * + * @brief Executes the cancel event action + * + * @param [in] event The cancel event. + */ + bool OnCancelEvent(const CancelEvent& event) override; + + /** + * @brief Enumerates the images for different button states. + * + * You can define a different image for each button state. + * + * @since 1.0 + * @version 1.0 + */ + enum ButtonImageSrc : uint8_t { + /* An enum constant representing the Button image default option */ + BTN_IMAGE_DEFAULT, + /* An enum constant representing the Button image triggered option */ + BTN_IMAGE_TRIGGERED, + /* An enum constant representing the Button Image Number option */ + BTN_IMG_NUM, + }; + + /** + * @brief Sets the image for this button. + * + * @param defaultImgSrc Indicates the default image. + * @param triggeredImgSrc Indicates the image for a button when it is triggered. + * @since 1.0 + * @version 1.0 + */ + void SetImageSrc(const char* defaultImgSrc, const char* triggeredImgSrc); + + /** + * @brief Sets the image for this button. + * + * @param defaultImgSrc Indicates the default image. + * @param triggeredImgSrc Indicates the image for a button when it is triggered. + * @since 1.0 + * @version 1.0 + */ + void SetImageSrc(const ImageInfo* defaultImgSrc, const ImageInfo* triggeredImgSrc); + + /** + * @brief Sets the position for this image. + * + * @param x Indicates the x-coordinate to set. + * @param y Indicates the y-coordinate to set. + * @since 1.0 + * @version 1.0 + */ + void SetImagePosition(const int16_t x, const int16_t y) + { + imgX_ = x; + imgY_ = y; + } + + /** + * @brief Obtains the x-coordinate of this image. + * + * @return Returns the x-coordinate of this image. + * @since 1.0 + * @version 1.0 + */ + int16_t GetImageX() const + { + return imgX_; + } + + /** + * @brief Obtains the y-coordinate of this image. + * + * @return Returns the y-coordinate of this image. + * @since 1.0 + * @version 1.0 + */ + int16_t GetImageY() const + { + return imgY_; + } + + /** + * @brief Obtains the image for the current button state. + * + * @return Returns the image for the current button state. + * @since 1.0 + * @version 1.0 + */ + const Image* GetCurImageSrc() const; + + /** + * @brief Enumerates the states of this button. + * + * The button has three states. + * + * @since 1.0 + * @version 1.0 + */ + enum ButtonState : uint8_t { + /* An enum constant representing the Button state released option */ + RELEASED = 0, + /* An enum constant representing the Button state pressed option */ + PRESSED, + /* An enum constant representing the Button state inactive option */ + INACTIVE, + /* An enum constant representing the Button state Number option */ + BTN_STATE_NUM, + }; + + /** + * @brief Obtains the width of this image. + * + * @return Returns the image width. + * @since 1.0 + * @version 1.0 + */ + int16_t GetWidth() override + { + Style* style = buttonStyles_[state_]; + return GetRelativeRect().GetWidth() - (style->paddingLeft_ + style->paddingRight_) - + (style->borderWidth_ * 2); /* 2: left and right border */ + } + + /** + * @brief Obtains the height of this image. + * + * @return Returns the image height. + * @since 1.0 + * @version 1.0 + */ + int16_t GetHeight() override + { + Style* style = buttonStyles_[state_]; + return GetRelativeRect().GetHeight() - (style->paddingTop_ + style->paddingBottom_) - + (style->borderWidth_ * 2); /* 2: top and bottom border */ + } + + /** + * @brief Sets the width for this image. + * + * @param width Indicates the width to set. + * @since 1.0 + * @version 1.0 + */ + void SetWidth(int16_t width) override + { + contentWidth_ = width; + Style* style = buttonStyles_[state_]; + UIView::SetWidth(width + (style->paddingLeft_ + style->paddingRight_) + + (style->borderWidth_ * 2)); /* 2: left and right border */ + } + + /** + * @brief Sets the height for this image. + * + * @param height Indicates the height to set. + * @since 1.0 + * @version 1.0 + */ + void SetHeight(int16_t height) override + { + contentHeight_ = height; + Style* style = buttonStyles_[state_]; + UIView::SetHeight(height + (style->paddingTop_ + style->paddingBottom_) + + (style->borderWidth_ * 2)); /* 2: top and bottom border */ + } + + /** + * @brief Obtains a rectangular area that contains coordinate information. + * + * @return Returns the rectangle area. + * @since 1.0 + * @version 1.0 + */ + virtual Rect GetContentRect() override + { + Rect contentRect; + Style* style = buttonStyles_[state_]; + contentRect.SetX(GetOrigRect().GetX() + style->paddingLeft_ + style->borderWidth_); + contentRect.SetY(GetOrigRect().GetY() + style->paddingTop_ + style->borderWidth_); + contentRect.SetWidth(GetWidth()); + contentRect.SetHeight(GetHeight()); + return contentRect; + } + + /** + * @brief Obtains the value of a style. + * + * @param key Indicates the key of the style. + * @return Returns the value of the style. + * @since 1.0 + * @version 1.0 + */ + int64_t GetStyle(uint8_t key) const override; + + /** + * @brief Sets a style. + * + * @param key Indicates the key of the style to set. + * @param value Indicates the value matching the key. + * @since 1.0 + * @version 1.0 + */ + void SetStyle(uint8_t key, int64_t value) override; + + /** + * @brief Obtains the style of a button in a specific state. + * + * @param key Indicates the key of the style. + * @param state Indicates the button state, as enumerated in {@link ButtonState}. + * @return Returns the style of the button in the specific state. + * @since 1.0 + * @version 1.0 + */ + int64_t GetStyleForState(uint8_t key, ButtonState state) const; + + /** + * @brief Sets the style for a button in a specific state. + * + * @param key Indicates the key of the style to set. + * @param value Indicates the value matching the key. + * @param state Indicates the button state, as enumerated in {@link ButtonState}. + * @since 1.0 + * @version 1.0 + */ + void SetStyleForState(uint8_t key, int64_t value, ButtonState state); + + /** + * @brief Disables this button. + * + * @since 1.0 + * @version 1.0 + */ + void Disable(); + + /** + * @brief Enables this button. + * + * @since 1.0 + * @version 1.0 + */ + void Enable(); + + /** + * @brief Sets the state for a button. After the setting, calling {@link SetStyle} + * will change the style of this button, but not its state. + * + * @param state Indicates the button state, as enumerated in {@link ButtonState}. + * @since 1.0 + * @version 1.0 + */ + void SetStateForStyle(ButtonState state) + { + styleState_ = state; + } + +protected: + Image* defaultImgSrc_; + Image* triggeredImgSrc_; + ButtonImageSrc currentImgSrc_; + int16_t imgX_; + int16_t imgY_; + int16_t contentWidth_; + int16_t contentHeight_; + void SetState(ButtonState state); + bool InitImage(); + + ButtonState state_; + ButtonState styleState_; + Style* buttonStyles_[BTN_STATE_NUM]; + bool buttonStyleAllocFlag_; + +private: + /** Sets up the theme styles */ + void SetupThemeStyles(); + + void DrawImg(const Rect& invalidatedArea, OpacityType opaScale); +}; +} // namespace OHOS +#endif // GRAPHIC_LITE_UI_BUTTON_H diff --git a/interfaces/kits/components/ui_canvas.h b/interfaces/kits/components/ui_canvas.h new file mode 100755 index 0000000..99a8d51 --- /dev/null +++ b/interfaces/kits/components/ui_canvas.h @@ -0,0 +1,681 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +/** + * @addtogroup UI_Components + * @{ + * + * @brief Defines UI components such as buttons, texts, images, lists, and progress bars. + * + * @since 1.0 + * @version 1.0 + */ + +/** + * @file ui_canvas.h + * + * @brief Defines the attributes of the canvas component and provides functions for drawing rectangles, + * circles, and others. + * + * @since 1.0 + * @version 1.0 + */ + +#ifndef GRAPHIC_LITE_UI_CANVAS_H +#define GRAPHIC_LITE_UI_CANVAS_H + +#include "common/image.h" +#include "components/ui_label.h" +#include "list.h" + +namespace OHOS { +/** + * @brief Defines the basic styles of graphs drawn on canvases. + * + * @since 1.0 + * @version 1.0 + */ +class Paint : public HeapBase { +public: + /** + * @brief A constructor used to create a Paint instance. + * + * @since 1.0 + * @version 1.0 + */ + Paint() + : style_(PaintStyle::STROKE_FILL_STYLE), fillColor_(Color::Black()), + strokeColor_(Color::White()), opacity_(OPA_OPAQUE), strokeWidth_(2) {} + + /** + * @brief A destructor used to delete the Paint instance. + * + * @since 1.0 + * @version 1.0 + */ + virtual ~Paint() {} + + /** + * @brief Enumerates paint styles of a closed graph. The styles are invalid for non-closed graphs. + */ + enum PaintStyle { + /** Stroke only */ + STROKE_STYLE = 1, + /** Fill only */ + FILL_STYLE, + /** Stroke and fill */ + STROKE_FILL_STYLE, + }; + + /** + * @brief Sets the paint style of a closed graph. + * + * @param style Indicates the paint style. Stroke and fill are set by default. For details, see {@link PaintStyle}. + * @see GetStyle + * @since 1.0 + * @version 1.0 + */ + void SetStyle(PaintStyle style) + { + style_ = style; + } + + /** + * @brief Obtains the paint style of a closed graph. + * + * @return Returns the paint style. For details, see {@link PaintStyle}. + * @see SetStyle + * @since 1.0 + * @version 1.0 + */ + PaintStyle GetStyle() const + { + return style_; + } + + /** + * @brief Sets the width of a line or border. + * + * @param width Indicates the line width when a line is drawn or the border width when a closed graph is drawn. + * The width is extended to both sides. + * @see GetStrokeWidth + * @since 1.0 + * @version 1.0 + */ + void SetStrokeWidth(uint16_t width) + { + strokeWidth_ = width; + } + + /** + * @brief Obtains the width of a line or border. + * + * @return Returns the line width if a line is drawn or the border width if a closed graph is drawn. + * @see SetStrokeWidth + * @since 1.0 + * @version 1.0 + */ + uint16_t GetStrokeWidth() const + { + return strokeWidth_; + } + + /** + * @brief Sets the color of a line or border. + * + * @param color Indicates the line color when a line is drawn or the border color when a closed graph is drawn. + * @see GetStrokeColor + * @since 1.0 + * @version 1.0 + */ + void SetStrokeColor(ColorType color) + { + strokeColor_ = color; + } + + /** + * @brief Obtains the color of a line or border. + * + * @return Returns the line color if a line is drawn or the border color if a closed graph is drawn. + * @see SetStrokeWidth + * @since 1.0 + * @version 1.0 + */ + ColorType GetStrokeColor() const + { + return strokeColor_; + } + + /** + * @brief Sets fill color. + * + * This function is valid only for closed graphs. + * + * @param color Indicates the fill color to set. + * @see GetFillColor + * @since 1.0 + * @version 1.0 + */ + void SetFillColor(ColorType color) + { + fillColor_ = color; + } + + /** + * @brief Obtains the fill color. + * + * @return Returns the fill color. + * @see SetFillColor + * @since 1.0 + * @version 1.0 + */ + ColorType GetFillColor() const + { + return fillColor_; + } + + /** + * @brief Sets the opacity. + * + * The setting takes effect for the entire graph, including the border, line color, and fill color. + * + * @param opacity Indicates the opacity. The value range is [0, 255]. + * @see GetOpacity + * @since 1.0 + * @version 1.0 + */ + void SetOpacity(uint8_t opacity) + { + opacity_ = opacity; + } + + /** + * @brief Obtains the opacity. + * + * @return Returns the opacity. + * @see SetOpacity + * @since 1.0 + * @version 1.0 + */ + uint8_t GetOpacity() const + { + return opacity_; + } + +private: + PaintStyle style_; + ColorType fillColor_; + ColorType strokeColor_; + uint8_t opacity_; + uint16_t strokeWidth_; +}; + +/** + * @brief Defines a canvas, which is used to draw multiple types of 2D graphs. + * + * @since 1.0 + * @version 1.0 + */ +class UICanvas : public UIView { +public: + /** + * @brief A constructor used to create a UICanvas instance. + * + * @since 1.0 + * @version 1.0 + */ + UICanvas() : startPoint_({ 0, 0 }), path_(nullptr) {} + + /** + * @brief A destructor used to delete the UICanvas instance. + * + * @since 1.0 + * @version 1.0 + */ + virtual ~UICanvas(); + + /** + * @brief Obtains the view type. + * + * @return Returns the view type. For details, see {@link UIViewType}. + * @since 1.0 + * @version 1.0 + */ + UIViewType GetViewType() const override + { + return UI_CANVAS; + } + + /** + * @brief Clears the entire canvas. + * + * @since 1.0 + * @version 1.0 + */ + void Clear(); + + /** + * @brief Sets the coordinates of the start point for drawing a line. For example, if startPoint is + * set to {50, 50}, the line is drawn from this set of coordinates on the canvas. + * + * @param startPoint Indicates the coordinates of the start point. + * @see GetStartPosition + * @since 1.0 + * @version 1.0 + */ + void SetStartPosition(const Point& startPoint) + { + startPoint_ = startPoint; + } + + /** + * @brief Obtains the coordinates of the start point of a line. + * + * @return Returns the coordinates of the start point. + * @see SetStartPosition + * @since 1.0 + * @version 1.0 + */ + const Point& GetStartPosition() const + { + return startPoint_; + } + + /** + * @brief Draws a straight line. + * + * If {@link SetStartPosition} is not used to set the coordinates of the start point of the line, the drawing + * starts from the end point of the last line. + * + * @param endPoint Indicates the end point of the straight line. + * @param paint Indicates the straight line style. For details, see {@link Paint}. + * @since 1.0 + * @version 1.0 + */ + void DrawLine(const Point& endPoint, const Paint& paint); + + /** + * @brief Draws a straight line from the coordinates of the start point. + * + * @param startPoint Indicates the coordinates of the start point. + * @param endPoint Indicates the coordinates of the end point. + * @param paint Indicates the straight line style. For details, see {@link Paint}. + * @since 1.0 + * @version 1.0 + */ + void DrawLine(const Point& startPoint, const Point& endPoint, const Paint& paint); + + /** + * @brief Draws a cubic Bezier curve. + * + * If {@link SetStartPosition} is not used to set the coordinates of the start point of the curve, + * the drawing starts from the end point of the last line. + * Currently, the opacity cannot be set, and the maximum line width is 3. + * + * @param control1 Indicates the coordinates of the first control point of the cubic Bezier curve. + * @param control2 Indicates the coordinates of the second control point of the cubic Bezier curve. + * @param endPoint Indicates the coordinates of the end point of the cubic Bezier curve. + * @param paint Indicates the curve style. For details, see {@link Paint}. + * @since 1.0 + * @version 1.0 + */ + void DrawCurve(const Point& control1, const Point& control2, const Point& endPoint, const Paint& paint); + + /** + * @brief Draws a cubic Bezier curve from the start point coordinates. + * + * Currently, the opacity cannot be set, and the maximum line width is 3. + * + * @param startPoint Indicates the coordinates of the start point of the cubic Bezier curve. + * @param control1 Indicates the coordinates of the first control point of the cubic Bezier curve. + * @param control2 Indicates the coordinates of the second control point of the cubic Bezier curve. + * @param endPoint Indicates the coordinates of the end point of the cubic Bezier curve. + * @param paint Indicates the curve style. For details, see {@link Paint}. + * @since 1.0 + * @version 1.0 + */ + void DrawCurve(const Point& startPoint, const Point& control1, const Point& control2, + const Point& endPoint, const Paint& paint); + + /** + * @brief Draws a rectangle. + * + * @param startPoint Indicates the coordinates of the point at the upper left corner of the rectangle. + * @param height Indicates the height of the rectangle. + * @param width Indicates the width of the rectangle. + * @param paint Indicates the rectangle style. For details, see {@link Paint}. + * @since 1.0 + * @version 1.0 + */ + void DrawRect(const Point& startPoint, int16_t height, int16_t width, const Paint& paint); + + /** + * @brief Draws a circle. + * + * @param center Indicates the coordinates of the circle center. + * @param radius Indicates the radius of the circle. + * @param paint Indicates the circle style. For details, see {@link Paint}. + * @since 1.0 + * @version 1.0 + */ + void DrawCircle(const Point& center, uint16_t radius, const Paint& paint); + + /** + * @brief Draws a sector. + * + * When the start angle is smaller than the end angle, the sector is drawn clockwise. + * Otherwise, the sector is drawn counterclockwise. + * + * @param center Indicates the coordinates of the sector's center. + * @param radius Indicates the radius of the sector. + * @param startAngle Indicates the start angle of the sector. Value 0 indicates the 12-o'clock direction, + * and 90 indicates the 3-o'clock direction. + * @param endAngle Indicates the end angle of the sector. Value 0 indicates the 12-o'clock direction, + * and 90 indicates the 3-o'clock direction. + * @param paint Indicates the sector style. For details, see {@link Paint}. + * @since 1.0 + * @version 1.0 + */ + void DrawSector(const Point& center, uint16_t radius, int16_t startAngle, int16_t endAngle, const Paint& paint); + + /** + * @brief Draws an arc. + * + * Only stroke is supported. \n + * When the start angle is smaller than the end angle, the sector is drawn clockwise. + * Otherwise, the sector is drawn counterclockwise. \n + * + * @param center Indicates the coordinates of the arc's center. + * @param radius Indicates the radius of the arc. + * @param startAngle Indicates the start angle of the arc. Value 0 indicates the 12-o'clock direction, + * and 90 indicates the 3-o'clock direction. + * @param endAngle Indicates the end angle of the arc. Value 0 indicates the 12-o'clock direction, + * and 90 indicates the 3-o'clock direction. + * @param paint Indicates the arc style. For details, see {@link Paint}. + * @since 1.0 + * @version 1.0 + */ + void DrawArc(const Point& center, uint16_t radius, int16_t startAngle, int16_t endAngle, const Paint& paint); + + /** + * @brief Draws an image. + * + * @param startPoint Indicates the coordinates of the start point. + * @param image Indicates the pointer to the image source. + * @param paint Indicates the image style. For details, see {@link Paint}. + * @since 1.0 + * @version 1.0 + */ + void DrawImage(const Point& startPoint, const char* image, const Paint& paint); + + /** + * @brief Defines the font style. + */ + struct FontStyle { + /** Text direction. For details, see {@link UITextLanguageDirect}. */ + UITextLanguageDirect direct; + /** Text alignment mode. For details, see {@link UITextLanguageAlignment}. */ + UITextLanguageAlignment align; + /** Font size */ + uint8_t fontSize; + /** Letter-spacing */ + int16_t letterSpace; + /** Font name */ + const char* fontName; + }; + + /** + * @brief Draws text. + * + * Only fill is supported. \n + * If the text length exceeds the value of maxWidth, the text will be truncated. \n + * + * @param startPoint Indicates the coordinates of the start point. + * @param text Indicates the pointer to the text content. + * @param maxWidth Indicates the maximum width of the text that can be displayed. If the maximum width is + * exceeded, the text is truncated. + * @param fontStyle Indicates the text layout and font style. For details, see {@link FontStyle}. + * @param paint Indicates the text style. For details, see {@link Paint}. + * @since 1.0 + * @version 1.0 + */ + void DrawLabel(const Point& startPoint, const char* text, uint16_t maxWidth, const FontStyle& fontStyle, + const Paint& paint); + + /** + * @brief Creates a path. + * + * A round corner can be used to join two lines. Currently, miter and bevel joints are not supported. + * To draw this path, you need to call {@link DrawPath}. + * + * @since 3.0 + * @version 5.0 + */ + void BeginPath(); + + /** + * @brief Moves the start point of this path to a specified point. + * + * @param point Indicates the specified point to move to. + * @since 3.0 + * @version 5.0 + */ + void MoveTo(const Point& point); + + /** + * @brief Creates a straight line from the end point of this path to a specified point. + * + * @param point Indicates the coordinates of the specified point. + * @since 3.0 + * @version 5.0 + */ + void LineTo(const Point& point); + + /** + * @brief Creates an arc path. + * + * @param center Indicates the coordinates of the arc's center point. + * @param radius Indicates the radius of the arc. + * @param startAngle Indicates the start angle of the arc. The value 0 indicates the 12-o'clock direction, + * and 90 indicates the 3-o'clock direction. + * @param endAngle Indicates the end angle of the arc. The value 0 indicates the 12-o'clock direction, + * and 90 indicates the 3-o'clock direction. + * @since 3.0 + * @version 5.0 + */ + void ArcTo(const Point& center, uint16_t radius, int16_t startAngle, int16_t endAngle); + + /** + * @brief Creates a rectangular path. + * + * @param point Indicates the coordinates of the rectangle's upper left corner. + * @param height Indicates the height of the rectangle. + * @param width Indicates the width of the rectangle. + * @since 3.0 + * @version 5.0 + */ + void AddRect(const Point& point, int16_t height, int16_t width); + + /** + * @brief Closes this path. + * + * @since 3.0 + * @version 5.0 + */ + void ClosePath(); + + /** + * @brief Draws this path. + * + * @param paint Indicates the path style. For details, see {@link Paint}. + * @since 3.0 + * @version 5.0 + */ + void DrawPath(const Paint& paint); + + void OnDraw(const Rect& invalidatedArea) override; + +protected: + constexpr static uint8_t MAX_CURVE_WIDTH = 3; + + struct LineParam : public HeapBase { + Point start; + Point end; + }; + + struct CurveParam : public HeapBase { + Point start; + Point control1; + Point control2; + Point end; + }; + + struct RectParam : public HeapBase { + Point start; + int16_t height; + int16_t width; + }; + + struct CircleParam : public HeapBase { + Point center; + uint16_t radius; + }; + + struct ArcParam : public HeapBase { + Point center; + uint16_t radius; + int16_t startAngle; + int16_t endAngle; + }; + + struct ImageParam : public HeapBase { + Point start; + uint16_t height; + uint16_t width; + Image* image; + }; + + enum PathCmd { + CMD_MOVE_TO, + CMD_LINE_TO, + CMD_ARC, + CMD_CLOSE, + }; + + class UICanvasPath : public HeapBase { + public: + UICanvasPath() : startPos_({ 0, 0 }), strokeCount_(0) {}; + ~UICanvasPath(); + List points_; + List cmd_; + List arcParam_; + Point startPos_; + uint16_t strokeCount_; + }; + + struct PathParam : public HeapBase { + UICanvasPath* path; + uint16_t count; + }; + + struct DrawCmd : public HeapBase { + Paint paint; + void* param; + void(*DrawGraphics)(void*, const Paint&, const Rect&, const Rect&, const Style&); + void(*DeleteParam)(void *); + }; + + Point startPoint_; + UICanvasPath* path_; + List drawCmdList_; + + static void DeleteLineParam(void* param) + { + LineParam* lineParam = static_cast(param); + delete lineParam; + } + + static void DeleteCurveParam(void* param) + { + CurveParam* curveParam = static_cast(param); + delete curveParam; + } + + static void DeleteRectParam(void* param) + { + RectParam* rectParam = static_cast(param); + delete rectParam; + } + + static void DeleteCircleParam(void* param) + { + CircleParam* circleParam = static_cast(param); + delete circleParam; + } + + static void DeleteArcParam(void* param) + { + ArcParam* arcParam = static_cast(param); + delete arcParam; + } + + static void DeleteImageParam(void* param) + { + ImageParam* imageParam = static_cast(param); + if (imageParam->image != nullptr) { + delete imageParam->image; + } + delete imageParam; + } + + static void DeleteLabel(void* param) + { + UILabel* label = static_cast(param); + delete label; + } + + static void DeletePathParam(void* param) + { + PathParam* pathParam = static_cast(param); + pathParam->path->strokeCount_--; + if (pathParam->path->strokeCount_ == 0) { + delete pathParam->path; + } + delete pathParam; + } + + static void DoDrawLine(void* param, const Paint& paint, const Rect& rect, const Rect& invalidatedArea, + const Style& style); + static void DoDrawCurve(void* param, const Paint& paint, const Rect& rect, const Rect& invalidatedArea, + const Style& style); + static void DoDrawRect(void* param, const Paint& paint, const Rect& rect, const Rect& invalidatedArea, + const Style& style); + static void DoFillRect(void* param, const Paint& paint, const Rect& rect, const Rect& invalidatedArea, + const Style& style); + static void DoDrawCircle(void* param, const Paint& paint, const Rect& rect, const Rect& invalidatedArea, + const Style& style); + static void DoDrawArc(void* param, const Paint& paint, const Rect& rect, const Rect& invalidatedArea, + const Style& style); + static void DoDrawImage(void* param, const Paint& paint, const Rect& rect, const Rect& invalidatedArea, + const Style& style); + static void DoDrawLabel(void* param, const Paint& paint, const Rect& rect, const Rect& invalidatedArea, + const Style& style); + static void DoDrawPath(void* param, const Paint& paint, const Rect& rect, const Rect& invalidatedArea, + const Style& style); + static void GetAbsolutePosition(const Point& prePoint, const Rect& rect, const Style& style, Point& point); + static void DoDrawLineJoin(const Point& center, const Rect& invalidatedArea, const Paint& paint); +}; +} // namespace OHOS +#endif // GRAPHIC_LITE_UI_CANVAS_H diff --git a/interfaces/kits/components/ui_chart.h b/interfaces/kits/components/ui_chart.h new file mode 100755 index 0000000..1624cd0 --- /dev/null +++ b/interfaces/kits/components/ui_chart.h @@ -0,0 +1,862 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +/** + * @addtogroup UI_Components + * @{ + * + * @brief Defines UI components such as buttons, texts, images, lists, and progress bars. + * + * @since 1.0 + * @version 1.0 + */ + +/** + * @file ui_chart.h + * + * @brief Defines the attributes of the chart component and provides functions for adding and deleting + * data sets to display a chart. + * + * @since 1.0 + * @version 1.0 + */ + +#ifndef GRAPHIC_LITE_UI_CHART_H +#define GRAPHIC_LITE_UI_CHART_H + +#include "components/ui_axis.h" +#include "components/ui_view_group.h" +#include "list.h" + +namespace OHOS { +class UIChart; +/** + * @brief Defines a data set and provides functions such as adding and deleting data points. + * + * @since 1.0 + * @version 1.0 + */ +class UIChartDataSerial : public HeapBase { +public: + /** + * @brief A constructor used to create a UIChartDataSerial instance. + * + * @since 1.0 + * @version 1.0 + */ + UIChartDataSerial(); + + /** + * @brief A destructor used to delete the UIChartDataSerial instance. + * + * @since 1.0 + * @version 1.0 + */ + virtual ~UIChartDataSerial() + { + if (pointArray_ != nullptr) { + UIFree(pointArray_); + pointArray_ = nullptr; + } + } + + /** + * @brief Sets the maximum number of data points that can be stored in a data set. + * + * This function must be called before data is added, deleted, or modified. Otherwise, data operations will fail. + * + * @param maxCount Indicates the number of data points. The default value is 0. + * + * @return Returns true if the operation is successful; returns false otherwise. + * @since 1.0 + * @version 1.0 + */ + bool SetMaxDataCount(uint16_t maxCount); + + /** + * @brief Modifies the value of a data point in the data set. + * + * @param index Indicates the index of the data point to modify. + * @param point Indicates the new value of the data point. + * + * @return Returns true if the operation is successful; returns false otherwise. + * @since 1.0 + * @version 1.0 + */ + bool ModifyPoint(uint16_t index, const Point& point); + + /** + * @brief Obtains the coordinates in the chart for a data point in the data set. + * + * @param index Indicates the index of the data point to obtain. + * @param point Indicates the obtained coordinates. If the data set is not added to the chart, + * the original value of the data point is printed. + * + * @return Returns true if the operation is successful; returns false otherwise. + * @since 1.0 + * @version 1.0 + */ + bool GetPoint(uint16_t index, Point& point); + + /** + * @brief Adds data points. + * + * The new data points are appended to the last added data. \n + * No more data points can be added if the maximum number is reached \n + * + * @param data Indicates the pointer to the start address of the data point. + * @param count Indicates the number of data points to add. + * @return Returns true if the data points are added successfully; returns false otherwise. + * @since 1.0 + * @version 1.0 + */ + bool AddPoints(const Point* data, uint16_t count); + + /** + * @brief Clears all data points. + * + * @since 1.0 + * @version 1.0 + */ + void ClearData(); + + /** + * @brief Obtains the number of data points available in the data set. + * + * @return Returns the number of data points. + * @since 1.0 + * @version 1.0 + */ + uint16_t GetDataCount() const + { + return dataCount_; + } + + /** + * @brief Sets whether to smooth a polyline. + * + * This function applies only to line charts. After the smoothing, some data is discarded. + * Therefore, the polyline does not pass through all data points. \n + * If smooth is set to true, the filling color, top point, and bottom point of a line chart have + * deviations. Therefore, you are advised not to use these functions at the same time. \n + * + * @param smooth Specifies whether to smooth a polyline. Value true means to smooth a polyline, and value + * false means not to smooth a polyline. The default value is false. + * @since 1.0 + * @version 1.0 + */ + void EnableSmooth(bool smooth) + { + smooth_ = smooth; + } + + /** + * @brief Checks whether smoothing is performed on a polyline. + * + * @return Returns true if smooth processing is performed on the polyline; returns false otherwise. + * @since 1.0 + * @version 1.0 + */ + bool IsSmooth() const + { + return smooth_; + } + + /** + * @brief Enables the fill color of a line chart. + * + * This function applies only to line charts. By default, the area between the polyline and the x-axis is filled. + * You can use {@link SetGradientBottom} to modify the filled region. \n + * + * @param enable Specifies whether to enable the fill color. Value true means to enable the fill color, + * and value false means to disable the fill color. The default value is false. + * @since 1.0 + * @version 1.0 + */ + void EnableGradient(bool enable) + { + enableGradient_ = enable; + } + + /** + * @brief Checks whether a polyline has a fill color. + * + * @return Returns true if there is a fill color; returns false otherwise. + * @since 1.0 + * @version 1.0 + */ + bool IsGradient() const + { + return enableGradient_; + } + + /** + * @brief Obtains the index of the top point in the data set. + * + * @return Returns the index of the top point. If there are multiple top points, the first one is returned. + * @since 1.0 + * @version 1.0 + */ + uint16_t GetPeakIndex() const + { + return peakPointIndex_; + } + + /** + * @brief Obtains the index of the frontmost point (the latest added or modified data point in a data set). + * + * @return Returns the index of the frontmost point. + * @since 1.0 + * @version 1.0 + */ + uint16_t GetLatestIndex() const + { + return latestIndex_; + } + + /** + * @brief Obtains the index of the bottom point in a data set. + * + * @return Returns the index of the bottom point. If there are multiple bottom points, the first one is returned. + * @since 1.0 + * @version 1.0 + */ + uint16_t GetValleyIndex() const + { + return valleyPointIndex_; + } + + /** + * @brief Obtains the Y value of the top point in a data set. + * + * The Y value is the data added by users, not the pixel coordinate. + * + * @return Returns the Y value. + * @since 1.0 + * @version 1.0 + */ + int16_t GetPeakData() const + { + return peakData_; + } + + /** + * @brief Obtains the Y value of the bottom point in a data set. + * + * The Y value is the data added by users, not the pixel coordinate. + * + * @return Returns the Y value. + * @since 1.0 + * @version 1.0 + */ + int16_t GetValleyData() const + { + return valleyData_; + } + + void SetLastPointIndex(uint16_t value) + { + lastPointIndex_ = value; + } + + uint16_t GetLastPointIndex() const + { + return lastPointIndex_; + } + + /** + * @brief Obtains the polyline color of the data set in a line chart. + * + * @return Returns the polyline color of the data set. + * @see SetLineColor + * @since 1.0 + * @version 1.0 + */ + ColorType GetLineColor() const + { + return serialColor_; + } + + /** + * @brief Obtains the fill color of the data set. + * + * @return Returns the fill color. + * @see SetFillColor + * @since 1.0 + * @version 1.0 + */ + ColorType GetFillColor() const + { + return fillColor_; + } + + /** + * @brief Sets the fill color of the data set. + * + * For a line chart, color refers to the fill color between the line and the x-axis. + * For a bar chart, color refers to the color of the bars. + * + * @param color Indicates the fill color to set. + * @see GetFillColor + * @since 1.0 + * @version 1.0 + */ + void SetFillColor(const ColorType& color) + { + fillColor_ = color; + } + + /** + * @brief Sets the polyline color of the data set in the line chart. + * + * This function applies only to line charts. + * + * @param color Indicates the polyline color to set. + * @see GetLineColor + * @since 1.0 + * @version 1.0 + */ + void SetLineColor(const ColorType& color) + { + serialColor_ = color; + } + + void BindToChart(UIChart* chart) + { + chart_ = chart; + } + + /** + * @brief Hides some points in the data set. + * + * This function applies only to line charts. After the points are hidden, the line connected by the points + * is not displayed. \n + * The top and bottom points may appear in the hidden region. If this method is enabled, + * you are not advised to enable the display of the top and bottom points. + * + * @param index Indicates the point from which the hide starts. + * @param count Indicates the number of points to hide. + * @since 1.0 + * @version 1.0 + */ + void HidePoint(uint16_t index, uint16_t count); + + /** + * @brief Obtains the index from which the data set starts to hide. + * + * @return Returns the index. + * @see HidePoint + * @since 1.0 + * @version 1.0 + */ + uint16_t GetHideIndex() const + { + return hideIndex_; + } + + /** + * @brief Obtains the number of hidden points in the data set. + * + * @return Returns the number of hidden points. + * @see HidePoint + * @since 1.0 + * @version 1.0 + */ + uint16_t GetHideCount() const + { + return hideCount_; + } + + /** + * @brief Defines the style for the top, bottom, and frontmost points in a line chart. + */ + struct PointStyle : public HeapBase { + /** Fill color */ + ColorType fillColor; + /** Border color */ + ColorType strokeColor; + /** Inner radius */ + uint16_t radius; + /** Border width, which extends outwards from the inner radius */ + uint16_t strokeWidth; + }; + + /** + * @brief Sets the style of the frontmost point on a polyline. + * + * @param style Indicates the style to set. For details, see {@link PointStyle}. + * @since 1.0 + * @version 1.0 + */ + void SetHeadPointStyle(const PointStyle& style) + { + headPointStyle_ = style; + } + + /** + * @brief Sets the style of the top point of a polyline. + * + * @param style Indicates the style to set. For details, see {@link PointStyle}. + * @since 1.0 + * @version 1.0 + */ + void SetTopPointStyle(const PointStyle& style) + { + topPointStyle_ = style; + } + + /** + * @brief Sets the style of the bottom point of a polyline. + * + * @param style Indicates the style to set. For details, see {@link PointStyle}. + * @since 1.0 + * @version 1.0 + */ + void SetBottomPointStyle(const PointStyle& style) + { + bottomPointStyle_ = style; + } + + /** + * @brief Obtains the style of the frontmost point on a polyline. + * + * @return Returns the style of the point. For details, see {@link PointStyle}. + * @since 1.0 + * @version 1.0 + */ + const PointStyle& GetHeadPointStyle() const + { + return headPointStyle_; + } + + /** + * @brief Obtains the style of the top point of a polyline. + * + * @return Returns the style of the point. For details, see {@link PointStyle}. + * @since 1.0 + * @version 1.0 + */ + const PointStyle& GetTopPointStyle() const + { + return topPointStyle_; + } + + /** + * @brief Obtains the style of the bottom point of a polyline. + * + * @return Returns the style of the point. For details, see {@link PointStyle}. + * @since 1.0 + * @version 1.0 + */ + const PointStyle& GetBottomPointStyle() const + { + return bottomPointStyle_; + } + + /** + * @brief Enables the feature of drawing the frontmost point on a polyline. + * + * @param enable Specifies whether to draw the frontmost point. Value true means to draw the frontmost + * point, and value false means not to draw the frontmost point. + * @since 1.0 + * @version 1.0 + */ + void EnableHeadPoint(bool enable) + { + enableHeadPoint_ = enable; + } + + /** + * @brief Enables the feature of drawing the top point of a polyline. If there are multiple top points, + * only the first one is drawn. + * + * @param enable Specifies whether to draw the top point. Value true means to draw the top point, + * and value false means not to draw the top point. + * @since 1.0 + * @version 1.0 + */ + void EnableTopPoint(bool enable) + { + enableTopPoint_ = enable; + } + + /** + * @brief Enables the feature of drawing the bottom point of a polyline. If there are multiple bottom points, + * only the first one is drawn. + * + * @param enable Specifies whether to draw the bottom point. Value true means to draw the bottom point, + * and value false means not to draw the bottom point. + * @since 1.0 + * @version 1.0 + */ + void EnableBottomPoint(bool enable) + { + enableBottomPoint_ = enable; + } + + void DrawPoint(const Rect& mask); + + void Refresh(); + +protected: + uint16_t maxCount_; + Point* pointArray_; + +private: + constexpr static uint16_t DEFAULT_POINT_RADIUS = 5; + constexpr static uint16_t MAX_POINTS_COUNT = 512; + + ColorType serialColor_; + ColorType fillColor_; + uint16_t dataCount_; + uint16_t peakPointIndex_; + int16_t peakData_; + int16_t valleyData_; + uint16_t valleyPointIndex_; + uint16_t lastPointIndex_; + uint16_t latestIndex_; + uint16_t hideIndex_; + uint16_t hideCount_; + bool smooth_ : 1; + bool enableGradient_ : 1; + bool enableHeadPoint_ : 1; + bool enableTopPoint_ : 1; + bool enableBottomPoint_ : 1; + PointStyle headPointStyle_; + PointStyle topPointStyle_; + PointStyle bottomPointStyle_; + UIChart* chart_; + Rect invalidateRect_; + void RefreshInvalidateRect(uint16_t startIndex, uint16_t endIndex); + void RefreshInvalidateRect(uint16_t pointIndex, const PointStyle& style); + bool UpdatePeakAndValley(uint16_t startPos, uint16_t endPos); + void DoDrawPoint(const Point& point, const PointStyle& style, const Rect& mask); +}; + +/** + * @brief Defines the chart class and provides functions such as adding and deleting data sets to display a chart. + * + * @since 1.0 + * @version 1.0 + */ +class UIChart : public UIViewGroup { +public: + /** + * @brief A constructor used to create a UIChart instance. + * + * @since 1.0 + * @version 1.0 + */ + UIChart() : enableReverse_(false), needRefresh_(false), mixData_(nullptr) + { + Add(&xAxis_); + Add(&yAxis_); + SetStyle(STYLE_LINE_WIDTH, 1); + SetStyle(STYLE_BACKGROUND_COLOR, Color::Black().full); + } + + /** + * @brief A destructor used to delete the UIChart instance. + * + * @since 1.0 + * @version 1.0 + */ + virtual ~UIChart(); + + /** + * @brief Obtains the view type. + * + * @return Returns the view type. For details, see {@link UIViewType}. + * @since 1.0 + * @version 1.0 + */ + UIViewType GetViewType() const override + { + return UI_CHART; + } + + /** + * @brief Sets the height for this component. + * + * @param height Indicates the height to set. + * @since 1.0 + * @version 1.0 + */ + void SetHeight(int16_t height) override; + + /** + * @brief Sets the width for this component. + * + * @param width Indicates the width to set. + * @since 1.0 + * @version 1.0 + */ + void SetWidth(int16_t width) override; + + bool OnPreDraw(Rect& invalidatedArea) const override + { + return false; + } + + void OnDraw(const Rect& invalidatedArea) override; + + /** + * @brief Adds a data set. + * + * @param dataSerial Indicates the pointer to the data set class. For details, see {@link UIChartDataSerial}. + * @return Returns true if the data set is added successfully; returns false otherwise. + * @see DeleteDataSerial + * @since 1.0 + * @version 1.0 + */ + virtual bool AddDataSerial(UIChartDataSerial* dataSerial); + + /** + * @brief Deletes a data set. + * + * @param dataSerial Indicates the pointer to the data set class. For details, see {@link UIChartDataSerial}. + * @return Returns true if the data set is deleted successfully; returns false otherwise. + * @see AddDataSerial + * @since 1.0 + * @version 1.0 + */ + virtual bool DeleteDataSerial(UIChartDataSerial* dataSerial); + + /** + * @brief Clears all data sets. + * + * @since 1.0 + * @version 1.0 + */ + virtual void ClearDataSerial(); + + /** + * @brief Refreshes a chart and redraws the dirty region. + * + * Only the parts that need to be redrawn are refreshed, for example, new data points. + * This function provides better performance than {@link Invalidate}. + * + * @since 1.0 + * @version 1.0 + */ + virtual void RefreshChart() = 0; + + /** + * @brief Obtains the x-axis instance. + * + * @return Returns the x-axis instance. + * @since 1.0 + * @version 1.0 + */ + UIXAxis& GetXAxis() + { + return xAxis_; + } + + /** + * @brief Obtains the y-axis instance. + * + * @return Returns the y-axis instance. + * @since 1.0 + * @version 1.0 + */ + UIYAxis& GetYAxis() + { + return yAxis_; + } + + /** + * @brief Enables chart reverse. + * + * After the chart is reversed, the x-axis aligns with the top of the chart. The pixel position corresponding + * to the data point remains unchanged. Complementary filling is performed on the chart + * (only the part that is not filled previously will be filled). + * + * @param enable Specifies whether to enable chart reverse. Value true means to enable chart reverse, + * and value false means not to enable chart reverse. The default value is false. + * @since 1.0 + * @version 1.0 + */ + void EnableReverse(bool enable) + { + if (enableReverse_ != enable) { + enableReverse_ = enable; + xAxis_.EnableReverse(enable); + yAxis_.EnableReverse(enable); + } + } + +protected: + List list_; + UIXAxis xAxis_; + UIYAxis yAxis_; + bool enableReverse_; + bool needRefresh_; + uint8_t* mixData_; + virtual void DrawDataSerials(const Rect& invalidatedArea) = 0; +}; + +/** + * @brief Provides special functions for implementing a bar chart. + * + * @since 1.0 + * @version 1.0 + */ +class UIChartPillar : public UIChart { +public: + /** + * @brief A constructor used to create a UIChartPillar instance. + * + * @since 1.0 + * @version 1.0 + */ + UIChartPillar() {} + + /** + * @brief A destructor used to delete the UIChartPillar instance. + * + * @since 1.0 + * @version 1.0 + */ + virtual ~UIChartPillar() {} + + /** + * @brief Refreshes a bar chart and redraws the dirty region. + * + * Only the parts that need to be redrawn are refreshed, for example, new data points. + * This function provides better performance than {@link Invalidate}. + * + * @since 1.0 + * @version 1.0 + */ + void RefreshChart() override; + +protected: + void DrawDataSerials(const Rect& invalidatedArea) override; + +private: + static constexpr float DEFAULT_MARK_PERCENTAGE = 0.1f; +}; + +/** + * @brief Provides special functions for implementing a polyline. + * + * @since 1.0 + * @version 1.0 + */ +class UIChartPolyline : public UIChart { +public: + /** + * @brief A constructor used to create a UIChartPolyline instance. + * + * @since 1.0 + * @version 1.0 + */ + UIChartPolyline() : minOpa_(OPA_TRANSPARENT), maxOpa_(OPA_OPAQUE), gradientBottom_(0) {} + + /** + * @brief A destructor used to delete the UIChartPolyline instance. + * + * @since 1.0 + * @version 1.0 + */ + virtual ~UIChartPolyline() {} + + /** + * @brief Refreshes a line chart and redraws the dirty region. + * + * Only the parts that need to be redrawn are refreshed, for example, new data points. + * This function provides better performance than {@link Invalidate}. + * + * @since 1.0 + * @version 1.0 + */ + void RefreshChart() override; + + /** + * @brief Sets the opacity range of the fill color gradient. + * + * This function sets the opacity range between the top point and bottom point of the line chart. + * The opacity of each horizontal line is calculated based on the ratio. + * + * @param minOpa Indicates the opacity closest to the x-axis. + * @param maxOpa Indicates the opacity farthest away from the x-axis. + * @since 1.0 + * @version 1.0 + */ + void SetGradientOpacity(uint8_t minOpa, uint8_t maxOpa) + { + minOpa_ = minOpa; + maxOpa_ = maxOpa; + needRefresh_ = true; + } + + /** + * @brief Sets the distance between the bottom edge of the fill color range and the x-axis. + * + * This function fills in the area between the polyline and bottom of the line chart. For a chart that is not + * reversed, if the bottom is above the polyline, there is no filling. For a reversed chart, + * if the bottom is below the polyline, there is no filling. + * + * @param bottom Indicates the bottom of the filling range. The value is the distance to the x-axis. + * @since 1.0 + * @version 1.0 + */ + void SetGradientBottom(uint16_t bottom) + { + gradientBottom_ = bottom; + } + +protected: + void DrawDataSerials(const Rect& invalidatedArea) override; + +private: + struct ChartLine { + Point start; + Point end; + }; + + struct CrossPointSet { + Point first; + Point second; + Point nextFirst; + bool firstFind; + bool secondFind; + }; + + constexpr static uint8_t SMOOTH_SLOPE_ANGLE = 3; + constexpr static uint8_t LINE_JOIN_WIDTH = 3; + uint8_t minOpa_; + uint8_t maxOpa_; + uint16_t gradientBottom_; + + void GradientColor(const Rect& invalidatedArea, UIChartDataSerial* data); + void DrawGradientColor(const Rect& invalidatedArea, + UIChartDataSerial* data, + const ChartLine& linePoints, + const ChartLine& limitPoints, + int16_t startY); + void DrawSmoothPolyLine(uint16_t startIndex, + uint16_t endIndex, + const Rect& invalidatedArea, + UIChartDataSerial* data); + void DrawPolyLine(uint16_t startIndex, uint16_t endIndex, const Rect& invalidatedArea, UIChartDataSerial* data); + bool GetLineCrossPoint(const Point& p1, const Point& p2, const Point& p3, const Point& p4, Point& cross); + void FindCrossPoints(const ChartLine& line, const ChartLine& polyLine, CrossPointSet& cross); + void ReMeasure() override; + void CalcVerticalInfo(int16_t top, int16_t bottom, int16_t start, int16_t end, int16_t& y, int16_t& yHeight); +}; +} // namespace OHOS +#endif // GRAPHIC_LITE_UI_CHART_H diff --git a/interfaces/kits/components/ui_checkbox.h b/interfaces/kits/components/ui_checkbox.h new file mode 100755 index 0000000..e98ad80 --- /dev/null +++ b/interfaces/kits/components/ui_checkbox.h @@ -0,0 +1,225 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +/** + * @addtogroup UI_Components + * @{ + * + * @brief Defines UI components such as buttons, texts, images, lists, and progress bars. + * + * @since 1.0 + * @version 1.0 + */ + +/** + * @file ui_checkbox.h + * + * @brief Defines the attributes and common functions of a check box. + * + * @since 1.0 + * @version 1.0 + */ + +#ifndef GRAPHIC_LITE_UI_CHECKBOX_H +#define GRAPHIC_LITE_UI_CHECKBOX_H + +#include "common/image.h" +#include "components/ui_view.h" + +namespace OHOS { +/** + * @brief Represents a check box. + * + * A check box permits users to make a binary choice. + * + * @since 1.0 + * @version 1.0 + */ +class UICheckBox : public UIView { +public: + /** + * @brief Enumerates the states of a check box. + * + * @since 1.0 + * @version 1.0 + */ + enum UICheckBoxState : uint8_t { + /* An enum constant representing the state selected option */ + SELECTED, + /* An enum constant representing the state unselected option */ + UNSELECTED, + /* Max num of state */ + MAX_STATUS_NUM, + }; + + /** + * @brief A constructor used to create a UICheckBox instance. + * + * @since 1.0 + * @version 1.0 + */ + UICheckBox(); + + /** + * @brief A destructor used to delete the UICheckBox instance. + * + * @since 1.0 + * @version 1.0 + */ + virtual ~UICheckBox(); + + /** + * @brief Represents a listener for changes of a check box. + * + * This is an inner class of UICheckBox. It contains a callback function to be invoked when the check box + * state changes. + * + * @see UICheckBox + * @since 1.0 + * @version 1.0 + */ + class OnChangeListener : public HeapBase { + public: + /** + * @brief Called when the state of this check box is switched. This is a virtual function, which needs your + * implementation. + * + * @param state Indicates the current state of this check box. For details, see {@link UICheckBoxState}. + * @since 1.0 + * @version 1.0 + */ + virtual bool OnChange(UICheckBoxState state) = 0; + + /** + * @brief A destructor used to delete the OnChangeListener instance. + * + * @since 1.0 + * @version 1.0 + */ + virtual ~OnChangeListener() {} + }; + + /** + * @brief Obtains the component type. + * + * @return Returns the component type, as defined in {@link UIViewType}. + * @since 1.0 + * @version 1.0 + */ + UIViewType GetViewType() const override + { + return UI_CHECK_BOX; + } + + /** + * @brief Sets the listener for this check box. + * + * The listener is triggered to invoke the callback function upon click events. + * + * @param listener Indicates the listener to set. For details, see {@link OnChangeListener}. + * @since 1.0 + * @version 1.0 + */ + void SetOnChangeListener(OnChangeListener* onStateChangeListener) + { + onStateChangeListener_ = onStateChangeListener; + } + + /** + * @fn virtual bool UICheckBox::OnPreDraw(Rect& invalidatedArea) override + * + * @brief Do something before draw, this function will be invoked mainly to check if this view need + * to cover invalidate area so render manager can decide which layer to draw firstly. + * @param [in] invalidate area. + * @returns True if need cover. + */ + bool OnPreDraw(Rect& invalidatedArea) const override + { + return false; + } + + /** + * @fn virtual void UICheckBox::OnDraw(const Rect& invalidatedArea) override; + * + * @brief Executes the draw action + * Ondraw invokes the rendering function provided by the underlying layer to draw pictures + * based on the selected status of the checkbox. + * + * @param [in] invalidatedArea The invalidated area. + */ + void OnDraw(const Rect& invalidatedArea) override; + + /** + * @fn virtual void UICheckBox::OnClickEvent(const ClickEvent& event) override; + * + * @brief Executes the click event action + * OnClickEvent will reverse the selected state of checkbox. + * Example: If the check box is selected, the checkbox status is changed to + * Unselected after the click action is taken. + * + * @param [in] event The event that passed when OnClickEvent is invoked. + * @return Returns true if the event is consumed; returns false otherwise. + */ + bool OnClickEvent(const ClickEvent& event) override; + + /** + * @brief Sets the images for this check box. + * + * @param selectedImageSrc Indicates the image for this check box when selected. + * @param unselectedImageSrc Indicates the image for this check box when unselected. + * @since 1.0 + * @version 1.0 + */ + virtual void SetImages(const char* selectedImageSrc, const char* unselectedImageSrc); + + /** + * @brief Sets the images for this check box. + * + * @param selectedImageSrc Indicates the image for this check box when selected. + * @param unselectedImageSrc Indicates the image for this check box when unselected. + * @since 1.0 + * @version 1.0 + */ + virtual void SetImages(const ImageInfo* selectedImageSrc, const ImageInfo* unselectedImageSrc); + + /** + * @brief Obtains the state of this check box. + * + * @return Returns the state of this check box, as defined in {@link UICheckBoxState}. + * @since 1.0 + * @version 1.0 + */ + UICheckBoxState GetState() const + { + return state_; + }; + + /** + * @brief Sets the state for this check box. + * + * @param state Indicates the state of this check box. For details, see {@link UICheckBoxState}. + * @since 1.0 + * @version 1.0 + */ + void SetState(UICheckBoxState state); + +protected: + virtual void ReverseState(); + UICheckBoxState state_; + OnChangeListener* onStateChangeListener_; + Image image_[MAX_STATUS_NUM]; +}; +} // namespace OHOS +#endif // GRAPHIC_LITE_UI_CHECKBOX_H diff --git a/interfaces/kits/components/ui_circle_progress.h b/interfaces/kits/components/ui_circle_progress.h new file mode 100755 index 0000000..9642b1f --- /dev/null +++ b/interfaces/kits/components/ui_circle_progress.h @@ -0,0 +1,260 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +/** + * @addtogroup UI_Components + * @{ + * + * @brief Defines UI components such as buttons, texts, images, lists, and progress bars. + * + * @since 1.0 + * @version 1.0 + */ + +/** + * @file ui_circle_progress.h + * + * @brief Defines the attributes and common functions of a circular progress bar. + * + * @since 1.0 + * @version 1.0 + */ + +#ifndef GRAPHIC_LITE_UI_CIRCLE_PROGRESS_H +#define GRAPHIC_LITE_UI_CIRCLE_PROGRESS_H + +#include "components/ui_abstract_progress.h" + +namespace OHOS { +/** + * @brief Represents a circular progress bar. + * + * This class is used to set the start and end angles, range, and current value to display the circular progress bar. + * + * @see UIAbstractProgress + * @since 1.0 + * @version 1.0 + */ +class UICircleProgress : public UIAbstractProgress { +public: + /** + * @brief A constructor used to create a UICircleProgress instance. + * + * @since 1.0 + * @version 1.0 + */ + UICircleProgress(); + + /** + * @brief A destructor used to delete the UICircleProgress instance. + * + * @since 1.0 + * @version 1.0 + */ + virtual ~UICircleProgress() {} + + /** + * @brief Obtains the view type. + * + * @return Returns the view type, as defined in {@link UIViewType}. + * @since 1.0 + * @version 1.0 + */ + UIViewType GetViewType() const override + { + return UI_CIRCLE_PROGRESS; + } + + bool OnPreDraw(Rect& invalidatedArea) const override + { + return false; + } + + void OnDraw(const Rect& invalidatedArea) override; + + /** + * @brief Sets the coordinates of the center point for this circular progress bar. + * + * The coordinates of the center point refer to the position relative to the view. + * + * @param x Indicates the x-coordinate to set. The default value is 0. + * @param y Indicates the y-coordinate to set. The default value is 0. + * @see GetCenterPosition + * @since 1.0 + * @version 1.0 + */ + void SetCenterPosition(int16_t x, int16_t y); + + /** + * @brief Obtains the coordinates of the center point for this circular progress bar. + * + * The coordinates of the center point refer to the position relative to the view. + * + * @return Returns the coordinates of the center point. + * @see SetCenterPosition + * @since 1.0 + * @version 1.0 + */ + Point GetCenterPosition() const + { + return center_; + } + + /** + * @brief Sets the outer radius for this circular progress bar. + * + * @param radius Indicates the outer radius to set. + * @see GetRadius + * @since 1.0 + * @version 1.0 + */ + void SetRadius(uint16_t radius) + { + radius_ = radius; + } + + /** + * @brief Obtains the outer radius of this circular progress bar. + * + * @return Returns the outer radius. + * @see SetRadius + * @since 1.0 + * @version 1.0 + */ + uint16_t GetRadius() const + { + return radius_; + } + + /** + * @brief Sets the start angle. + * + * The 12-clock direction is 0 degrees, and the 3-clock direction is 90 degrees. \n + * If the start angle is smaller than the end angle, the progress bar is clockwise. + * Otherwise, the progress bar is anticlockwise. \n + * The maximum range of a progress bar is a circle. If the difference between the start angle and end angle + * exceeds 360 degrees, a circular progress bar is created. \n + * + * @param startAngle Indicates the start angle to set, which can be any value represented by int16_t. + * The default value is 0. + * @see GetStartAngle | SetEndAngle + * @since 1.0 + * @version 1.0 + */ + void SetStartAngle(int16_t startAngle); + + /** + * @brief Obtains the start angle. + * + * @return Returns the start angle. + * @see SetStartAngle + * @since 1.0 + * @version 1.0 + */ + int16_t GetStartAngle() const + { + return startAngle_; + } + + /** + * @brief Sets the end angle. + * + * The 12-clock direction is 0 degrees, and the 3-clock direction is 90 degrees. \n + * If the start angle is smaller than the end angle, the progress bar is clockwise. + * Otherwise, the progress bar is anticlockwise. \n + * The maximum range of a progress bar is a circle. If the difference between the start angle and end angle + * exceeds 360 degrees, a circular progress bar is created. \n + * + * @param endAngle Indicates the end angle to set, which can be any value represented by int16_t. + * The default value is 360. + * @see GetEndAngle | SetStartAngle + * @since 1.0 + * @version 1.0 + */ + void SetEndAngle(int16_t endAngle); + + /** + * @brief Obtains the end angle. + * + * @return Returns the end angle. + * @see SetEndAngle + * @since 1.0 + * @version 1.0 + */ + int16_t GetEndAngle() const + { + return endAngle_; + } + + /** + * @brief Sets the coordinates of the foreground image for this progress bar relative to the view. + * + * @param x Indicates the x-coordinate to set. The default value is 0. + * @param y Indicates the y-coordinate to set. The default value is 0. + * @see SetBackgroundImagePosition + * @since 1.0 + * @version 1.0 + */ + void SetProgressImagePosition(int16_t x, int16_t y) + { + progressImagePos_.x = x + style_->paddingLeft_ + style_->borderWidth_; + progressImagePos_.y = y + style_->paddingTop_ + style_->borderWidth_; + } + + /** + * @brief Sets the coordinates of the background image for this progress bar relative to the view. + * + * @param x Indicates the x-coordinate to set. The default value is 0. + * @param y Indicates the y-coordinate to set. The default value is 0. + * @see SetProgressImagePosition + * @since 1.0 + * @version 1.0 + */ + void SetBackgroundImagePosition(int16_t x, int16_t y) + { + backgroundImagePos_.x = x + style_->paddingLeft_ + style_->borderWidth_; + backgroundImagePos_.y = y + style_->paddingTop_ + style_->borderWidth_; + } + + /** + * @brief Sets the foreground color for this progress bar. + * + * @param color Indicates the foreground color to set. For details, see {@link ColorType}. + * @since 1.0 + * @version 1.0 + */ + void SetLineColor(ColorType color) + { + SetForegroundStyle(STYLE_LINE_COLOR, color.full); + } + +private: + static constexpr uint16_t MAX_ANGLE_VALUE = CIRCLE_IN_DEGREE; + static constexpr uint16_t MIN_ANGLE_VALUE = 0; + + void GetStartEndAngle(int16_t& start, int16_t& end) const; + void GetAngleRange(int16_t& start, int16_t& end) const; + void GetRedrawAngle(int16_t& start, int16_t& end) const; + void DrawCommonCircle(const Rect& invalidatedArea); + + Point center_; + Point backgroundImagePos_; + Point progressImagePos_; + uint16_t radius_; + int16_t startAngle_; + int16_t endAngle_; +}; +} // namespace OHOS +#endif // GRAPHIC_LITE_UI_CIRCLE_PROGRESS_H diff --git a/interfaces/kits/components/ui_dialog.h b/interfaces/kits/components/ui_dialog.h new file mode 100755 index 0000000..f30c9fe --- /dev/null +++ b/interfaces/kits/components/ui_dialog.h @@ -0,0 +1,248 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +/** + * @addtogroup UI_Components + * @{ + * + * @brief Defines UI components such as buttons, texts, images, lists, and progress bars. + * + * @since 1.0 + * @version 1.0 + */ + +/** + * @file ui_dialog.h + * + * @brief Declares the UIDialog class that defines the dialog box component. + * + * @since 1.0 + * @version 1.0 + */ + +#ifndef GRAPHIC_LITE_UI_DIALOG_H +#define GRAPHIC_LITE_UI_DIALOG_H + +#include "components/root_view.h" +#include "components/ui_label.h" +#include "components/ui_label_button.h" + +#if ENABLE_WINDOW +namespace OHOS { +/** + * @brief Represents a dialog box. + * + * A dialog box displays information for user input. + * After a button is clicked in the dialog box, the corresponding callback event is triggered. + * + * @since 1.0 + * @version 1.0 + */ +class UIDialogClickListener; +class UIDialog : public HeapBase { +public: + /** + * @brief A constructor used to create a UIDialog instance. + * + * @since 1.0 + * @version 1.0 + */ + UIDialog(); + + /** + * @brief A destructor used to delete the UIDialog instance. + * + * @since 1.0 + * @version 1.0 + */ + virtual ~UIDialog(); + + /** + * @brief Enumerates buttons in a dialog box. + * + * @since 1.0 + * @version 1.0 + */ + enum class DialogButtonType { + /** Left button */ + BUTTON_LEFT, + /** Middle button */ + BUTTON_MID, + /** Right button */ + BUTTON_RIGHT, + }; + + /** + * @brief Sets the title for this dialog box. + * + * @param title Indicates the pointer to the title. + * @since 1.0 + * @version 1.0 + */ + void SetTitle(const char* title); + + /** + * @brief Sets the text for this dialog box. + * + * @param text Indicates the pointer to the text. + * @since 1.0 + * @version 1.0 + */ + void SetText(const char* text); + + /** + * @brief Sets a button for this dialog box. + * + * @param buttonType Indicates the button position. + * @param text Indicates the pointer to the button text. + * @param listener Indicates the pointer to the listener registered for the button. + * @since 1.0 + * @version 1.0 + */ + void SetButton(DialogButtonType buttonType, const char* text, UIView::OnClickListener* listener); + + /** + * @brief Shows this dialog box. + * + * @since 5.0 + * @version 3.0 + */ + void Show(); + + /** + * @brief Sets the button color. + * + * @param buttonType Indicates the button type. + * @param color Indicates the button color to set. + * @since 5.0 + * @version 3.0 + */ + void SetButtonColor(DialogButtonType buttonType, ColorType color); + + /** + * @brief Sets a listener for monitoring click events occurring outside this dialog box. + * + * @param onCancelListener Indicates the pointer to the listener to set. + * @since 5.0 + * @version 3.0 + */ + void SetOnCancelListener(UIView::OnClickListener* onCancelListener); + + /** + * @brief Sets whether to close this dialog box when click events occur outside it. + * + * @param enable Specifies whether to close this dialog box when click events occur outside it. + * @since 5.0 + * @version 3.0 + */ + void EnableAutoCancel(bool enable); + +#ifdef ENABLE_DEBUG + const char* GetTitle() const + { + return titleText_; + } + + const char* GetText() const + { + return textText_; + } + + const char* GetButtonText(DialogButtonType buttonType) const; + + UIView::OnClickListener* GetButtonListener(DialogButtonType buttonType) const; + + ColorType GetButtonColor(DialogButtonType buttonType) const; + + UIView::OnClickListener* GetOnCancelListener() const + { + return onCancelListener_; + } + + bool GetEnableAutoCancel() const + { + return enableAutoCancel_; + } +#endif + +private: + const static uint8_t BUTTON_HEIGHT = 40; + const static uint8_t BUTTON_TOTAL_HEIGHT = 56; + const static uint8_t PADDING = 24; + const static uint8_t BUTTON_MID_PADDING = 10; + const static uint8_t BUTTON_PADDING = 16; + const static uint8_t BUTTON_PRESS_OPA = 26; // 10% opacity + const static uint8_t TEXT_BUTTON_PADDING = 8; + const static uint8_t TEXT_FONT_SIZE = 16; + const static uint8_t TITLE_FONT_SIZE = 20; + const static uint8_t TITLE_TOTAL_HEIGHT = 56; + const static uint8_t BUTTON_FONT_SIZE = 16; + const static uint16_t MAX_WIDTH_PERCENT = 60; + const static uint16_t MAX_HEIGHT_PERCENT = 90; + const static uint8_t TITLE_TEXT_OPA = 230; // 90% opacity + const static uint8_t LINE_BUTTON_PADDING = 4; + const static uint8_t LINE_WIDTH = 2; + const static uint8_t LINE_HEIGHT = 24; + const static uint8_t LINE_BOTTOM_PADDING = 24; + const static uint8_t LINE_OPA = 51; // 20% opacity + const char* TITLE_ID = "dialogTitle"; + const char* BUTTON1_ID = "dialogButton1"; + const char* BUTTON2_ID = "dialogButton2"; + + void AddButton(DialogButtonType buttonType, UILabelButton* button, const char* text, + UIView::OnClickListener* listener); + void InitDialog(); + void SetTitleLabel(); + void SetTextLabel(); + void AddComponents(); + void MeasureSize(); + uint16_t MeasureMaxWidth(); + uint16_t MeasureTitleWidth(); + uint16_t MeasureTextWidth(); + uint16_t MeasureButtonWidth(); + void Layout(); + void LayoutButton(); + void CreateDialogWindow(); + void DestoryWindow(); + + bool isShowing_; + bool enableAutoCancel_; + uint8_t buttonNum_; + UILabel* title_; + UILabel* text_; + UILabelButton* button1_; + UILabelButton* button2_; + UILabelButton* button3_; + UIViewGroup* dialogLayer_; + uint16_t widthMax_; + uint16_t heightMax_; + RootView* windowRootView_; + UIView::OnClickListener* onCancelListener_; + UIDialogClickListener* dialogClickListener_; + Window* window_; + UIView* line1_; + UIView* line2_; + const char* titleText_; + const char* textText_; + ColorType colorType1_; + ColorType colorType2_; + ColorType colorType3_; + + friend class UIDialogLabelButton; + friend class UIDialogClickListener; +}; +} +#endif // GRAPHIC_LITE_UI_DIALOG_H +#endif // ENABLE_WINDOW \ No newline at end of file diff --git a/interfaces/kits/components/ui_digital_clock.h b/interfaces/kits/components/ui_digital_clock.h new file mode 100755 index 0000000..2042f62 --- /dev/null +++ b/interfaces/kits/components/ui_digital_clock.h @@ -0,0 +1,222 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +/** + * @addtogroup UI_Components + * @{ + * + * @brief Defines UI components such as buttons, texts, images, lists, and progress bars. + * + * @since 1.0 + * @version 1.0 + */ + +/** + * @file ui_digital_clock.h + * + * @brief Declares a digital clock. + * + * @since 1.0 + * @version 1.0 + */ + +#ifndef GRAPHIC_LITE_UI_DIGITAL_CLOCK_H +#define GRAPHIC_LITE_UI_DIGITAL_CLOCK_H + +#include "color.h" +#include "components/ui_abstract_clock.h" +#include "components/ui_label.h" + +namespace OHOS { +/** + * @brief Displays time digitally. + * + * @see UIDigitalClock + * @since 1.0 + * @version 1.0 + */ +class UIDigitalClock : public UIAbstractClock { +public: + /** + * @brief A default constructor used to create a UIDigitalClock instance. + * + * @since 1.0 + * @version 1.0 + */ + UIDigitalClock(); + + /** + * @brief A destructor used to delete the UIDigitalClock instance. + * + * @since 1.0 + * @version 1.0 + */ + virtual ~UIDigitalClock(); + + /** + * @brief Obtains the view type. + * + * @return Returns UI_DIGITAL_CLOCK, as defined in {@link UIViewType}. + * @since 1.0 + * @version 1.0 + */ + UIViewType GetViewType() const override + { + return UI_DIGITAL_CLOCK; + } + + /** + * @brief Sets the dynamic font ID for this digital clock. + * + * @param fontId Indicates the dynamic font ID to set. + * @since 1.0 + * @version 1.0 + */ + void SetFontId(uint8_t fontId); + + /** + * @brief Sets the dynamic font for this digital clock. + * + * @param name Indicates the pointer to the font name. + * @param size Indicates the font size to set. + * @since 1.0 + * @version 1.0 + */ + void SetFont(const char* name, uint8_t size); + + /** + * @brief Sets the font color for this digital clock. + * + * @param color Indicates the front color to set. + * @since 1.0 + * @version 1.0 + */ + void SetColor(ColorType color); + + /** + * @brief Enumerates the display modes of this digital clock. + */ + enum DisplayMode : uint8_t { + /** 12-hour format, without seconds */ + DISPLAY_12_HOUR_NO_SECONDS, + /** 24-hour format, without seconds */ + DISPLAY_24_HOUR_NO_SECONDS, + /** 12-hour format */ + DISPLAY_12_HOUR, + /** 24-hour format */ + DISPLAY_24_HOUR + }; + + /** + * @brief Enumerates the time elements of this digital clock. + */ + enum TimeElement : uint8_t { + /** Clock */ + HOUR_ELEMENT = 0, + /** Minute */ + MINUTE_ELEMENT, + /** Second */ + SECOND_ELEMENT + }; + + /** + * @brief Sets the display mode for this digital clock. + * + * @param dm Indicates the display mode to set. + * @since 1.0 + * @version 1.0 + */ + void SetDisplayMode(DisplayMode dm) + { + displayMode_ = dm; + UpdateClock(false); + } + + /** + * @brief Obtains the display mode of this digital clock. + * + * @return Returns the display mode of this digital clock. + * @since 1.0 + * @version 1.0 + */ + DisplayMode GetDisplayMode() const + { + return displayMode_; + } + + /** + * @brief Sets whether to add 0 before the hour of this digital clock. + * + * @param displayLeadingZero Specifies whether to add 0 before the hour of this digital clock. + * true indicates that 0 is added, and false indicates + * the opposite case. + * @since 1.0 + * @version 1.0 + */ + void DisplayLeadingZero(bool displayLeadingZero); + + /** + * @brief Sets the opacity for this digital clock. + * + * @param opacity Indicates the opacity of this digital clock. The value ranges + * from 0 (transparency) to 255 (opacity). + * @since 1.0 + * @version 1.0 + */ + void SetOpacity(uint8_t opacity); + + /** + * @brief Obtains the opacity of this digital clock. + * + * @return Returns the opacity of this digital clock, within [0, 255]. + * @since 1.0 + * @version 1.0 + */ + uint8_t GetOpacity() const; + + /** + * @brief Updates this digital clock. + * + * @param clockInit Specifies whether the first initialization. true indicates the first initialization, + * and false indicates the opposite case. + * @since 1.0 + * @version 1.0 + */ + void UpdateClock(bool clockInit) override; + +protected: + static constexpr uint8_t TIME_ELEMENT_COUNT = 3; + UILabel* timeLabels_[TIME_ELEMENT_COUNT]; + + virtual void InitTimeLabels(); + +private: + static constexpr uint8_t BUFFER_SIZE = 4; + void SetHorizontal(); + void SetVertical(); + void SetTimeLabels(const char buf[TIME_ELEMENT_COUNT][BUFFER_SIZE]); + void SetTimeLabelsPosition(); + void TimeElementRefresh(); + void RefreshTime(); + DisplayMode displayMode_; + bool leadingZero_; + ColorType color_; + uint8_t prevHour_; + uint8_t prevMinute_; + uint8_t prevSecond_; + bool verticalShow_; +}; +} // namespace OHOS +#endif // UI_DIGITAL_CLOCK_H diff --git a/interfaces/kits/components/ui_image_animator.h b/interfaces/kits/components/ui_image_animator.h new file mode 100755 index 0000000..b100a7c --- /dev/null +++ b/interfaces/kits/components/ui_image_animator.h @@ -0,0 +1,484 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +/** + * @addtogroup UI_Components + * @{ + * + * @brief Defines UI components such as buttons, texts, images, lists, and progress bars. + * + * @since 1.0 + * @version 1.0 + */ + +/** + * @file ui_image_animator.h + * + * @brief Defines the attributes and functions of an image animator. + * + * @since 1.0 + * @version 1.0 + */ + +#ifndef GRAPHIC_LITE_UI_IMAGE_ANIMATOR_H +#define GRAPHIC_LITE_UI_IMAGE_ANIMATOR_H + +#include "animator/animator.h" +#include "components/ui_image_view.h" +#include "graphic_types.h" + +namespace OHOS { +/** + * @brief Provides information about the images. + */ +struct ImageAnimatorInfo { + union { + /** Image path */ + const char* imagePath; + /** Pointer to the {@link ImageInfo} structure */ + const ImageInfo* imageInfo; + }; + /** Image start position, relative to this view */ + Point pos; + /** Image width */ + int16_t width; + /** Image height */ + int16_t height; + /** Image type */ + ImageType imageType; +}; + +/** + * @brief Represents an image animator. + * + * Images are switched at a specified interval to form an animator. + * + * @see UIImageView + * @since 1.0 + * @version 1.0 + */ +class UIImageAnimatorView : public UIImageView { +public: + /** + * @brief A constructor used to create a UIImageAnimatorView instance. + * + * @since 1.0 + * @version 1.0 + */ + UIImageAnimatorView(); + + /** + * @brief A destructor used to delete the UIImageAnimatorView instance. + * + * @since 1.0 + * @version 1.0 + */ + virtual ~UIImageAnimatorView(); + + /** + * @brief Obtains the view type. + * + * @return Returns the view type, as defined in {@link UIViewType}. + * @since 1.0 + * @version 1.0 + */ + UIViewType GetViewType() const override + { + return UI_IMAGE_ANIMATOR_VIEW; + } + + /** + * @brief Sets the images and speed for this animator. + * + * @param imageSrc Indicates the pointer to the {@link ImageAnimatorInfo} array for storing the configured + * image information. The memory cannot be released before this animator stops. + * @param imageNum Indicates the number of images. + * @param timeOfUpdate Indicates the interval for updating images, in milliseconds. The default value is 1. + * @see GetTimeOfUpdate | GetImageAnimatorSrc | GetImageAnimatorImageNum + * @since 1.0 + * @version 1.0 + */ + void SetImageAnimatorSrc(const ImageAnimatorInfo imageSrc[], uint8_t imageNum, uint16_t timeOfUpdate); + + /** + * @brief Sets the images for this animator. + * + * @param imageSrc Indicates the pointer to the {@link ImageAnimatorInfo} array for storing the configured + * image information. The memory cannot be released before this animator stops. + * @param imageNum Indicates the number of images. + * @see GetImageAnimatorSrc | GetImageAnimatorImageNum + * @since 1.0 + * @version 1.0 + */ + void SetImageAnimatorSrc(const ImageAnimatorInfo imageSrc[], uint8_t imageNum); + + /** + * @brief Sets the speed for this animator. + * + * @param timeOfUpdate Indicates the interval for updating images, in milliseconds. The default value is 1. + * @see GetTimeOfUpdate + * @since 1.0 + * @version 1.0 + */ + void SetTimeOfUpdate(uint16_t timeOfUpdate); + + /** + * @brief Obtains the speed of this animator. + * + * @return Returns the interval for updating images, in milliseconds. + * @see SetTimeOfUpdate + * @since 1.0 + * @version 1.0 + */ + uint16_t GetTimeOfUpdate() const; + + /** + * @brief Sets the interval between two playbacks of an infinitely repeated animator. + * + * @param timeOfPause Indicates the interval between two playbacks of an infinitely repeated animator, in + * milliseconds. The default value is 0, indicating that there is no interval. + * @see GetTimeOfPause + * @since 1.0 + * @version 1.0 + */ + void SetTimeOfPause(uint16_t timeOfPause); + + /** + * @brief Obtains the interval between two playbacks of an infinitely repeated animator. + * + * @return Returns the interval between two playbacks, in milliseconds. + * @see SetTimeOfPause + * @since 1.0 + * @version 1.0 + */ + uint16_t GetTimeOfPause() const; + + /** + * @brief Obtains the image array of this frame animator. + * + * @return Returns a pointer to the {@link ImageAnimatorInfo} array if the operation is successful; + * returns nullptr otherwise. + * @since 1.0 + * @version 1.0 + */ + const ImageAnimatorInfo* GetImageAnimatorSrc() const; + + /** + * @brief Obtains the number of images. + * + * @return Returns the number of images. + * @since 1.0 + * @version 1.0 + */ + uint8_t GetImageAnimatorImageNum() const; + + /** + * @brief Sets whether the image size is fixed to the view size. + * + * @param fixed Specifies whether the image size is fixed to the view size. The value true indicates + * the size of the image is the same as that of the view, and false indicates the + * position and size of this image need to be set in the {@link ImageAnimatorInfo} structure. + * @see IsSizeFixed + * @since 1.0 + * @version 1.0 + */ + void SetSizeFixed(bool fixed) + { + sizeFixed_ = fixed; + } + + /** + * @brief Checks whether the image size is fixed to the view size. + * + * @return Returns true if the image size is fixed to the view size; + * returns false if the image size is set independently. + * @see SetSizeFixed + * @since 1.0 + * @version 1.0 + */ + bool IsSizeFixed() const + { + return sizeFixed_; + } + + /** + * @brief Sets whether to play this animator for infinite times. + * + * @param repeat Specifies whether the animator is played for infinite times. true (default value) + * indicates the animator is played for infinite times, and false indicates the animator + * is played a specified number of times. + * @see IsRepeat + * @since 1.0 + * @version 1.0 + */ + void SetRepeat(bool repeat) + { + repeat_ = repeat; + } + + /** + * @brief Checks whether this animator is played for infinite times. + * + * @return Returns true if this animator is played for infinite times, returns false if the + * animator is played a specified number of times. + * @see SetRepeat + * @since 1.0 + * @version 1.0 + */ + bool IsRepeat() const + { + return repeat_; + } + + /** + * @brief Sets the playback times for this animator. + * + * This function takes effect only when repeat is set to false in {@link SetRepeat}. + * + * @param times Indicates the playback times to set. The default value is 1. + * @see GetRepeatTimes + * @since 1.0 + * @version 1.0 + */ + void SetRepeatTimes(uint32_t times) + { + repeatTimes_ = times; + } + + /** + * @brief Obtains the playback times. + * + * @return Returns the playback times. + * @see SetRepeatTimes + * @since 1.0 + * @version 1.0 + */ + uint32_t GetRepeatTimes() const + { + return repeatTimes_; + } + + /** + * @brief Obtains the current state of this animator. + * + * @return Returns the current state, which can be {@link START}, {@link STOP}, or {@link PAUSE}. + * For details, see {@link Animator}. + * @since 1.0 + * @version 1.0 + */ + uint8_t GetState() const + { + return imageAnimator_.GetState(); + } + + /** + * @brief Sets the playback sequence for this animator. + * + * @param reverse Indicates the playback sequence to set. true indicates a reverse playback + * and false (default value) indicates a forward playback. + * @see IsReverse + * @since 1.0 + * @version 1.0 + */ + void SetReverse(bool reverse) + { + reverse_ = reverse; + } + + /** + * @brief Obtains the playback sequence of this animator. + * + * @return Returns true if a reverse playback is performed; + * returns false if a forward playback is performed. + * @see SetReverse + * @since 1.0 + * @version 1.0 + */ + bool IsReverse() const + { + return reverse_; + } + + /** + * @brief Sets the attribute value for the end frame of this animator. + * + * @param fillMode Indicates the attribute value for the end frame of this animator. + * When a forward playback is performed, the value true indicates setting the end frame of + * this animator to the last one of the image set, and false indicates setting the end frame + * of this animator to the first one of the image set. When a reverse playback is performed, + * the value true indicates setting the end frame of this animator to the first one of + * the image set, and false indicates setting the end frame of this animator to the last one + * of the image set. The default value is true. + * @see GetFillMode + * @since 3.0 + * @version 5.0 + */ + void SetFillMode(bool fillMode) + { + fillMode_ = fillMode; + } + + /** + * @brief Obtains the attribute value of the last frame of this animator. + * + * @return Returns true if the last frame of this animator is the last one of the image set when + * a forward playback is performed, or if the last frame of this animator is the first one of the image set + * when a reverse playback is performed; + * returns false if the last frame of this animator is the first one of the image set when + * a forward playback is performed, or if the last frame of this animator is the last one of the image set + * when a reverse playback is performed. + * + * @see SetFillMode + * @since 3.0 + * @version 5.0 + */ + bool GetFillMode() const + { + return fillMode_; + } + + /** + * @brief Starts this animator. + * + * The forward playback starts from the first image and the reverse playback starts from the last image. + * + * @see Stop + * @since 1.0 + * @version 1.0 + */ + void Start(); + + /** + * @brief Stops this animator. + * + * @see Start + * @since 1.0 + * @version 1.0 + */ + void Stop(); + + /** + * @brief Pauses this animator at the current image. + * + * @see Resume + * @since 1.0 + * @version 1.0 + */ + void Pause() + { + imageAnimator_.SetState(Animator::PAUSE); + } + + /** + * @brief Resumes this animator from the current image. + * + * @see Pause + * @since 1.0 + * @version 1.0 + */ + void Resume() + { + imageAnimator_.SetState(Animator::START); + } + + /** + * @brief Represents a listener that contains a callback to be invoked when this animator stops. + * + * @since 1.0 + * @version 1.0 + */ + class AnimatorStopListener : public HeapBase { + public: + /** + * @brief A destructor used to delete an AnimatorStopListener instance. + * + * @since 1.0 + * @version 1.0 + */ + virtual ~AnimatorStopListener() {} + + /** + * @brief Called when this animator stops. + * + * You need to inherit from the AnimatorStopListener class and implement this function. + * + * @param view Indicates the instance of this view. + * @since 1.0 + * @version 1.0 + */ + virtual void OnAnimatorStop(UIView& view) {} + }; + + /** + * @brief Sets the listener for the stop of this animator. + * + * @param listener Indicates the listener to set. For details, see {@link AnimatorStopListener}. + * @since 1.0 + * @version 1.0 + */ + void SetAnimatorStopListener(AnimatorStopListener* listener) + { + listener_ = listener; + } + +protected: + class ImageAnimatorCallback : public AnimatorCallback { + public: + ImageAnimatorCallback() + : tickNum_(0), loop_(1), drawingImage_(0), repeat_(0), + imageSrc_(nullptr), imageNum_(0) + { + }; + + virtual ~ImageAnimatorCallback() {} + + virtual void Callback(UIView* view) override; + + void Reset() + { + tickNum_ = 0; + loop_ = 1; + repeat_ = 0; + } + + protected: + uint16_t tickNum_; + uint8_t loop_; + uint8_t drawingImage_; + uint32_t repeat_; + const ImageAnimatorInfo* imageSrc_; + uint8_t imageNum_; + }; + + void Reset(bool fillMode); + void UpdateImage(uint8_t& drawingImage, uint8_t& loop); + uint8_t GetTickByTime(uint16_t time) const; + ImageAnimatorInfo* imageSrc_; + uint8_t imageNum_; + uint8_t tickOfUpdate_; + uint16_t timeOfUpdate_; + uint16_t timeOfPause_; + uint8_t tickOfPause_; + uint32_t repeatTimes_; + Animator imageAnimator_; + ImageAnimatorCallback imageAnimatorCallback_; + AnimatorStopListener* listener_; + bool reverse_; + bool repeat_; + bool sizeFixed_; + bool fillMode_; +}; +} +#endif // GRAPHIC_LITE_UI_IMAGE_ANIMATOR_H diff --git a/interfaces/kits/components/ui_image_view.h b/interfaces/kits/components/ui_image_view.h new file mode 100755 index 0000000..f3acdfe --- /dev/null +++ b/interfaces/kits/components/ui_image_view.h @@ -0,0 +1,305 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +/** + * @addtogroup UI_Components + * @{ + * + * @brief Defines UI components such as buttons, texts, images, lists, and progress bars. + * + * @since 1.0 + * @version 1.0 + */ + +/** + * @file ui_image_view.h + * + * @brief Declares an image view. + * + * @since 1.0 + * @version 1.0 + */ + +#ifndef GRAPHIC_LITE_UI_IMAGE_VIEW_H +#define GRAPHIC_LITE_UI_IMAGE_VIEW_H + +#include "common/image.h" +#include "components/ui_view.h" +#include "graphic_types.h" +#ifndef VERSION_LITE +#include "animator/animator.h" +#endif + +namespace OHOS { +/** + * @brief Defines the functions related to an image view. + * + * @since 1.0 + * @version 1.0 + */ +class UIImageView : public UIView { +public: + /** + * @brief A default constructor used to create a UIImageView instance. + * + * @since 1.0 + * @version 1.0 + */ + UIImageView(); + + /** + * @brief A destructor used to delete the UIImageView instance. + * + * @since 1.0 + * @version 1.0 + */ + virtual ~UIImageView(); + + /** + * @brief Obtains the view type. + * + * @return Returns UI_IMAGE_VIEW, as defined in {@link UIViewType}. + * @since 1.0 + * @version 1.0 + */ + UIViewType GetViewType() const override + { + return UI_IMAGE_VIEW; + } + + /** + * @brief Obtains the width of this image view. + * + * @return Returns the width of this image view. + * @since 1.0 + * @version 1.0 + */ + int16_t GetWidth() override + { + if (needRefresh_ && autoEnable_) { + ReMeasure(); + } + return UIView::GetWidth(); + } + + /** + * @brief Obtains the height of this image view. + * + * @return Returns the height of this image view. + * @since 1.0 + * @version 1.0 + */ + int16_t GetHeight() override + { + if (needRefresh_ && autoEnable_) { + ReMeasure(); + } + return UIView::GetHeight(); + } + + /** + * @brief Checks whether this image view needs to be covered to optimize the drawing process. + * + * @param invalidatedArea Indicates the area to draw. + * @return Returns true if this image view needs to be covered; returns false otherwise. + * @since 1.0 + * @version 1.0 + */ + bool OnPreDraw(Rect& invalidatedArea) const override; + + /** + * @brief Draws this image view. + * + * @param invalidatedArea Indicates the area to draw. + * @since 1.0 + * @version 1.0 + */ + void OnDraw(const Rect& invalidatedArea) override; + + /** + * @brief Sets the image path. + * + * @param src Indicates the pointer to the image path represented by a string. + * @since 1.0 + * @version 1.0 + */ + void SetSrc(const char* src); + + /** + * @brief Sets the image information. + * + * @param src Indicates the pointer to the image information. For details, see {@link ImageInfo}. + * @since 1.0 + * @version 1.0 + */ + void SetSrc(const ImageInfo* src); + + /** + * @brief Sets whether the image view size needs to be adaptive to the image size. + * + * @param enable Specifies whether the image view size needs to be adaptive to the image size. + * true indicates that automatic adaption is enabled, and false indicates the opposite case. + * @since 1.0 + * @version 1.0 + */ + void SetAutoEnable(bool enable) + { + if (autoEnable_ != enable) { + needRefresh_ = autoEnable_ ? needRefresh_ : true; + autoEnable_ = enable; + } + } + + /* + * @brief Checks whether automatic adaptation is enabled. + * + * @return Returns true if automatic adaptation is enabled; returns false otherwise. + * @since 1.0 + * @version 1.0 + */ + bool GetAutoEnable() const + { + return autoEnable_; + } + + /** + * @brief Sets the blur level for this image when it is rotated or scaled. + * + * @param level Indicates the blur level to set. For details, see {@link BlurLevel}. + * @since 1.0 + * @version 1.0 + */ + void SetBlurLevel(BlurLevel level) + { + blurLevel_ = level; + } + + /** + * @brief Obtains the blur level of this image when it is rotated or scaled. + * + * @return Returns the blur level of this image, as defined in {@link BlurLevel}. + * @since 1.0 + * @version 1.0 + */ + BlurLevel GetBlurLevel() const + { + return static_cast(blurLevel_); + } + + /** + * @brief Sets the algorithm used for image rotation and scaling. + * + * @param algorithm Indicates the image transformation algorithm. For details, see {@link TransformAlgorithm}. + * @since 1.0 + * @version 1.0 + */ + void SetTransformAlgorithm(TransformAlgorithm algorithm) + { + algorithm_ = algorithm; + } + + /** + * @brief Obtains the algorithm used for image rotation and scaling. + * + * @return Returns the image transform algorithm, as defined in {@link TransformAlgorithm}. + * @since 1.0 + * @version 1.0 + */ + TransformAlgorithm GetTransformAlgorithm() const + { + return static_cast(algorithm_); + } + + /** + * @brief Obtains the image path in binary. + * + * @return Returns the pointer to the image path. + * @since 1.0 + * @version 1.0 + */ + const char* GetPath() const + { + return image_.GetPath(); + } + + /** + * @brief Obtains the image information in an array. + * + * @return Returns the pointer to the image information. + * @since 1.0 + * @version 1.0 + */ + const ImageInfo* GetImageInfo() const + { + return image_.GetImageInfo(); + } + + /** + * @brief Obtains the image type. + * + * @return Returns IMG_SRC_VARIABLE for image information in an array; returns IMG_SRC_FILE for an + * image path in binary. + * @since 1.0 + * @version 1.0 + */ + uint8_t GetSrcType() const + { + return image_.GetSrcType(); + } + +protected: + /** + * @brief Represents the width of this image. + */ + int16_t imageWidth_; + /** + * @brief Represents the height of this image. + */ + int16_t imageHeight_; + /** + * @brief Specifies whether automatic adaptation is enabled. + */ + bool autoEnable_; + /** + * @brief Specifies whether a refresh is needed. + */ + bool needRefresh_; + /** + * @brief Represents the color format of this image. + */ + uint8_t colorFormat_ : 4; + /** + * @brief Represents the blur level of this image when it is rotated or scaled. + */ + uint8_t blurLevel_ : 2; + /** + * @brief Represents the algorithm used for image rotation and scaling. + */ + uint8_t algorithm_ : 1; + uint8_t reserve_ : 1; + Image image_; + +private: + void ReMeasure() override; +#ifndef VERSION_LITE + friend class GifImageAnimator; + void AddAndStartGifAnimator(); + void RemoveAndStopGifAnimator(); + Animator* gifImageAnimator_; + bool gifFrameFlag_; +#endif +}; +} // namespace OHOS +#endif // GRAPHIC_LITE_UI_IMAGE_VIEW_H \ No newline at end of file diff --git a/interfaces/kits/components/ui_label.h b/interfaces/kits/components/ui_label.h new file mode 100755 index 0000000..66d64bb --- /dev/null +++ b/interfaces/kits/components/ui_label.h @@ -0,0 +1,443 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +/** + * @addtogroup UI_Components + * @{ + * + * @brief Defines UI components such as buttons, texts, images, lists, and progress bars. + * + * @since 1.0 + * @version 1.0 + */ + +/** + * @file ui_label.h + * + * @brief Declares a UILabel class that represents a label. + * + * @since 1.0 + * @version 1.0 + */ + +#ifndef GRAPHIC_LITE_UI_LABEL_H +#define GRAPHIC_LITE_UI_LABEL_H + +#include "animator/animator.h" +#include "common/text.h" +#include "components/ui_view.h" + +namespace OHOS { +/** + * @brief Defines the functions for presenting a label in a specified area, setting the style and background color + * of a label, and setting the display mode of a long label text. + * + * @since 1.0 + * @version 1.0 + */ +class UILabel : public UIView { +public: + /** + * @brief Enumerates the display modes of a long text. + */ + enum LineBreakMode : uint8_t { + /** + * The label size is adaptive to the text size. + */ + LINE_BREAK_ADAPT = 0, + /** + * The height of this label remains unchanged, and the width is adaptive to the text size. + */ + LINE_BREAK_STRETCH, + /** + * The width of this label remains unchanged, and the height is adaptive to the text size. + * The text switches to the next line if the text exceeds the maximum label width. + */ + LINE_BREAK_WRAP, + /** + * The width and height of this label remain unchanged. + * If this text is too long, ellipsis will be used at the end. + */ + LINE_BREAK_ELLIPSIS, + /** + * The width and height of this label remain unchanged. + * If this text is too long, it will be rolled to display. + */ + LINE_BREAK_MARQUEE, + /** + * The width and height of this label remain unchanged. + * If this text is too long, it will be cropped to display. + */ + LINE_BREAK_CLIP, + /** + * Maximum value of the line break mode, which is used for validity check. + */ + LINE_BREAK_MAX, + }; + + /** + * @brief A constructor used to create a UILabel instance. + * + * @since 1.0 + * @version 1.0 + */ + UILabel(); + + /** + * @brief A destructor used to delete the UILabel instance. + * + * @since 1.0 + * @version 1.0 + */ + virtual ~UILabel(); + + /** + * @brief Obtains the view type. + * + * @return Returns UI_LABEL, as defined in {@link UIViewType}. + * @since 1.0 + * @version 1.0 + */ + UIViewType GetViewType() const override + { + return UI_LABEL; + } + + /** + * @brief Obtains the width of this label. + * + * @return Returns the label width. + * @since 1.0 + * @version 1.0 + */ + int16_t GetWidth() override; + + /** + * @brief Obtains the height of this label. + * + * @return Returns the label height. + * @since 1.0 + * @version 1.0 + */ + int16_t GetHeight() override; + + /** + * @brief Sets the view style. + * @param style Indicates the view style. + * @since 1.0 + * @version 1.0 + */ + void SetStyle(Style& style) override + { + UIView::SetStyle(style); + } + + /** + * @brief Sets a style. + * + * @param key Indicates the key of the style to set. + * @param value Indicates the value matching the key. + * @since 1.0 + * @version 1.0 + */ + void SetStyle(uint8_t key, int64_t value) override; + + /** + * @brief Checks whether this label needs to be covered before drawing it. + * + * @param invalidatedArea Indicates the area to draw. + * @return Returns true if this label needs to be covered; returns false otherwise. + * @since 1.0 + * @version 1.0 + */ + bool OnPreDraw(Rect& invalidatedArea) const override + { + return false; + } + + /** + * @brief Draws this label. + * + * @param invalidatedArea Indicates the area to draw. + * @since 1.0 + * @version 1.0 + */ + void OnDraw(const Rect& invalidatedArea) override; + + /** + * @brief Sets the text content for this label. + * + * @param text Indicates the pointer to the text content. + * @since 1.0 + * @version 1.0 + */ + void SetText(const char* text); + + /** + * @brief Obtains the text of this label. + * + * @return Returns the text. + * @since 1.0 + * @version 1.0 + */ + const char* GetText() const + { + return (labelText_ == nullptr) ? nullptr : labelText_->GetText(); + } + + /** + * @brief Sets the line break mode for this text. + * + * @param lineBreakMode Indicates the line break mode to set. + * @since 1.0 + * @version 1.0 + */ + void SetLineBreakMode(const uint8_t lineBreakMode); + + /** + * @brief Obtains the line break mode of this text. + * + * @return Returns the line break mode. + * @since 1.0 + * @version 1.0 + */ + uint8_t GetLineBreakMode() const + { + return lineBreakMode_; + } + + /** + * @brief Sets the color for this text. + * + * @param color Indicates the text color to set. + * @since 1.0 + * @version 1.0 + */ + void SetTextColor(ColorType color) + { + useTextColor_ = true; + textColor_ = color; + } + + /** + * @brief Obtains the color of this text. + * + * @return Returns the text color. + * @since 1.0 + * @version 1.0 + */ + ColorType GetTextColor() const + { + return useTextColor_ ? textColor_ : GetStyleConst().textColor_; + } + + /** + * @brief Sets the alignment mode for this text. + * + * @param horizontalAlign Indicates the horizontal alignment mode to set, + * which can be {@link TEXT_ALIGNMENT_LEFT}, + * {@link TEXT_ALIGNMENT_CENTER}, or {@link TEXT_ALIGNMENT_RIGHT}. + * @param verticalAlign Indicates the vertical alignment mode to set, which can be + * {@link TEXT_ALIGNMENT_TOP} (default mode), {@link TEXT_ALIGNMENT_CENTER}, + * or {@link TEXT_ALIGNMENT_BOTTOM}. + * @since 1.0 + * @version 1.0 + */ + void SetAlign(UITextLanguageAlignment horizontalAlign, + UITextLanguageAlignment verticalAlign = TEXT_ALIGNMENT_TOP); + + /** + * @brief Obtains the horizontal alignment mode. + * + * @return Returns the horizontal alignment mode. + * @since 1.0 + * @version 1.0 + */ + UITextLanguageAlignment GetHorAlign() + { + InitLabelText(); + return labelText_->GetHorAlign(); + } + + /** + * @brief Obtains the vertical alignment mode. + * + * @return Returns the vertical alignment mode. + * @since 1.0 + * @version 1.0 + */ + UITextLanguageAlignment GetVerAlign() + { + InitLabelText(); + return labelText_->GetVerAlign(); + } + + /** + * @brief Sets the direction for this text. + * + * @return direct Returns the text direction, as defined in {@link UITextLanguageDirect}. + * @since 1.0 + * @version 1.0 + */ + void SetDirect(UITextLanguageDirect direct) + { + InitLabelText(); + labelText_->SetDirect(direct); + } + + /** + * @brief Obtains the direction of this text. + * + * @return Returns the text direction, as defined in {@link UITextLanguageDirect}. + * @since 1.0 + * @version 1.0 + */ + UITextLanguageDirect GetDirect() + { + InitLabelText(); + return labelText_->GetDirect(); + } + + /** + * @brief Sets the font ID for this label. + * + * @param fontId Indicates the font ID composed of font name and size. + * @since 1.0 + * @version 1.0 + */ + void SetFontId(uint8_t fontId); + + /** + * @brief Obtains the font ID composed of font name and size. + * + * @return Returns the front ID of this label. + * @since 1.0 + * @version 1.0 + */ + uint8_t GetFontId() + { + InitLabelText(); + return labelText_->GetFontId(); + } + + /** + * @brief Sets the font for this label. + * + * @param name Indicates the pointer to the font name. + * @param size Indicates the font size to set. + * @since 1.0 + * @version 1.0 + */ + void SetFont(const char* name, uint8_t size); + + /** + * @brief Sets the scroll speed for this text. + * + * @param speed Indicates the scroll speed to set. + * @since 1.0 + * @version 1.0 + */ + void SetRollSpeed(uint16_t speed); + + /** + * @brief Obtains the width of this text. + * + * @return Returns the text width. + * @since 1.0 + * @version 1.0 + */ + uint16_t GetTextWidth(); + + /** + * @brief Obtains the height of this text. + * + * @return Returns the text height. + * @since 1.0 + * @version 1.0 + */ + uint16_t GetTextHeight(); + + /** + * @brief Sets the position where this text starts to roll. + * + * @param pos Indicates the position to set. + * @since 1.0 + * @version 1.0 + */ + void SetRollStartPos(int16_t pos); + + /** + * @brief Obtains the position where this text starts to roll. + * + * @return Returns the position where this text starts to roll. + * @since 1.0 + * @version 1.0 + */ + int16_t GetRollStartPos() const; + + /** + * @brief Sets the width for this label. + * + * @param width Indicates the width to set. + * @since 1.0 + * @version 1.0 + */ + void SetWidth(int16_t width) override; + + /** + * @brief Sets the height for this label. + * + * @param height Indicates the height to set. + * @since 1.0 + * @version 1.0 + */ + void SetHeight(int16_t height) override; + +protected: + Text* labelText_; + void RefreshLabel(); + + virtual void InitLabelText() + { + if (labelText_ == nullptr) { + labelText_ = new Text(); + } + } + +private: + friend class LabelAnimator; + + void ReMeasure() override; + void RemeasureForMarquee(int16_t textWidth); + + bool needRefresh_ : 1; + bool useTextColor_ : 1; + bool hasAnimator_ : 1; + uint8_t lineBreakMode_ : 4; + uint16_t ellipsisIndex_; + int16_t offsetX_; + ColorType textColor_; + + static constexpr uint16_t DEFAULT_ANIMATOR_SPEED = 35; + union { + Animator* animator; + struct { + uint16_t speed; + int16_t pos; + }; + } animator_; +}; +} // namespace OHOS +#endif // GRAPHIC_LITE_UI_LABEL_H diff --git a/interfaces/kits/components/ui_label_button.h b/interfaces/kits/components/ui_label_button.h new file mode 100755 index 0000000..efe4f81 --- /dev/null +++ b/interfaces/kits/components/ui_label_button.h @@ -0,0 +1,312 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +/** + * @addtogroup UI_Components + * @{ + * + * @brief Defines UI components such as buttons, texts, images, lists, and progress bars. + * + * @since 1.0 + * @version 1.0 + */ + +/** + * @file ui_label_button.h + * + * @brief Declares a label button. + * + * @since 1.0 + * @version 1.0 + */ + +#ifndef GRAPHIC_LITE_UI_LABEL_BUTTON_H +#define GRAPHIC_LITE_UI_LABEL_BUTTON_H + +#include "common/text.h" +#include "components/ui_button.h" +#include "graphic_log.h" + +namespace OHOS { +/** + * @brief Provides the functions related to a label button. + * + * @since 1.0 + * @version 1.0 + */ +class UILabelButton : public UIButton { +public: + /** + * @brief A constructor used to create a UILabelButton instance. + * + * @since 1.0 + * @version 1.0 + */ + UILabelButton(); + + /** + * @brief A destructor used to delete the UILabelButton instance. + * + * @since 1.0 + * @version 1.0 + */ + virtual ~UILabelButton(); + + /** + * @brief Draws a label button. + * + * @since 1.0 + * @version 1.0 + */ + void OnDraw(const Rect& invalidatedArea) override; + + /** + * @brief Obtains the view type. + * + * @return Returns UI_LABEL_BUTTON, as defined in {@link UIViewType}. + * @since 1.0 + * @version 1.0 + */ + UIViewType GetViewType() const override + { + return UI_LABEL_BUTTON; + } + + /** + * @brief Sets the text for this label button. + * + * @param text Indicates the pointer to the text. + * @since 1.0 + * @version 1.0 + */ + void SetText(const char* text) + { + InitLabelButtonText(); + labelButtonText_->SetText(text); + } + + /** + * @brief Obtains the text of this label button. + * + * @return Returns the text. + * @since 1.0 + * @version 1.0 + */ + const char* GetText() const + { + return (labelButtonText_ == nullptr) ? nullptr : labelButtonText_->GetText(); + } + + /** + * @brief Sets the position for this label relative to the button holding it. + * + * @param x Indicates the offset distance by which this label is moved on the x-axis. + * @param y Indicates the offset distance by which this label is moved on the y-axis. + * @since 1.0 + * @version 1.0 + */ + void SetLablePosition(int16_t x, int16_t y) + { + offset_.x = x; + offset_.y = y; + } + + /** + * @brief Obtains the position of this label relative to the button holding it. + * + * @return Returns the position of this label. + * @since 1.0 + * @version 1.0 + */ + Point GetLabelPosition() const + { + return offset_; + } + + /** + * @brief Sets the alignment mode for this text. + * + * @param align Indicates the text alignment mode to set, as defined in {@link UITextLanguageAlignment}. + * @since 1.0 + * @version 1.0 + */ + void SetAlign(UITextLanguageAlignment align) + { + InitLabelButtonText(); + labelButtonText_->SetAlign(align, TEXT_ALIGNMENT_CENTER); + } + + /** + * @brief Obtains the alignment mode of this text. + * + * @return Returns the text alignment mode, as defined in {@link UITextLanguageAlignment}. + * @since 1.0 + * @version 1.0 + */ + UITextLanguageAlignment GetAlign() + { + InitLabelButtonText(); + return labelButtonText_->GetHorAlign(); + } + + /** + * @brief Sets the direction for this text. + * + * @param direct Indicates the text direction to set, as defined in {@link UITextLanguageDirect}. + * @since 1.0 + * @version 1.0 + */ + void SetDirect(UITextLanguageDirect direct) + { + InitLabelButtonText(); + labelButtonText_->SetDirect(direct); + } + + /** + * @brief Obtains the direction of this text. + * + * @return Returns the text direction, as defined in {@link UITextLanguageDirect}. + * @since 1.0 + * @version 1.0 + */ + UITextLanguageDirect GetDirect() + { + InitLabelButtonText(); + return labelButtonText_->GetDirect(); + } + + /** + * @brief Sets the style for this label. + * + * @param labelStyle Indicates the label style to set. + * @since 1.0 + * @version 1.0 + */ + void SetLabelStyle(Style& labelStyle) + { + labelStyle_ = labelStyle; + } + + /** + * @brief Sets a style for this label. + * + * @param key Indicates the key of the style to set. + * @param value Indicates the value matching the key. + * @since 1.0 + * @version 1.0 + */ + void SetLabelStyle(uint8_t key, int64_t value) + { + labelStyle_.SetStyle(key, value); + } + + /** + * @brief Obtains the style of this label. + * + * @return Returns the label style. + * @since 1.0 + * @version 1.0 + */ + const Style& GetLabelStyle() const + { + return labelStyle_; + } + + /** + * @brief Obtains the value of a style of this label. + * + * @param key Indicates the key of the style. + * @return Returns the value of the style. + * @since 1.0 + * @version 1.0 + */ + int64_t GetLabelStyle(uint8_t key) const + { + return labelStyle_.GetStyle(key); + } + + /** + * @brief Sets the color for this text. + * + * @param color Indicates the text color to set. + * @since 1.0 + * @version 1.0 + */ + void SetTextColor(ColorType color) + { + labelStyle_.textColor_ = color; + } + + /** + * @brief Sets the font for this text. + * + * @param name Indicates the pointer to the font name. + * @param size Indicates the font size to set. + * @since 1.0 + * @version 1.0 + */ + void SetFont(const char* name, uint8_t size) + { + InitLabelButtonText(); + labelButtonText_->SetFont(name, size); + } + + /** + * @brief Sets the font ID. + * + * @param fontId Indicates the font ID composed of the font name and size. + * @since 1.0 + * @version 1.0 + */ + void SetFontId(uint8_t fontId) + { + InitLabelButtonText(); + labelButtonText_->SetFontId(fontId); + } + + /** + * @brief Obtains the font ID. + * + * @return Returns the front ID composed of the font name and size. + * @since 1.0 + * @version 1.0 + */ + uint8_t GetFontId() + { + InitLabelButtonText(); + return labelButtonText_->GetFontId(); + } + +protected: + virtual void InitLabelButtonText() + { + if (labelButtonText_ == nullptr) { + labelButtonText_ = new Text(); + if (labelButtonText_ == nullptr) { + GRAPHIC_LOGE("new Text fail"); + return; + } + labelButtonText_->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); + } + } + + Text* labelButtonText_; + +private: + Style labelStyle_; + Point offset_; /* Text draw position offset */ +}; +} // namespace OHOS +#endif // GRAPHIC_LITE_UI_LABEL_BUTTON_H diff --git a/interfaces/kits/components/ui_list.h b/interfaces/kits/components/ui_list.h new file mode 100755 index 0000000..8d2f406 --- /dev/null +++ b/interfaces/kits/components/ui_list.h @@ -0,0 +1,449 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +/** + * @addtogroup UI_Components + * @{ + * + * @brief Defines UI components such as buttons, texts, images, lists, and progress bars. + * + * @since 1.0 + * @version 1.0 + */ + +/** + * @file ui_list.h + * + * @brief Declares a scrollable list in the vertical or horizontal direction. * This scrollable list can be used with + * the adapter {@link AbstractAdapter} to implement scrolling, inertial scrolling, automatic alignment, and + * invoking of a callback when a child view at the preset position is selected as this list scrolls. It is used + * when there is a large number of child views with a fixed format. + * + * @since 1.0 + * @version 1.0 + */ + +#ifndef GRAPHIC_LITE_UI_LIST_H +#define GRAPHIC_LITE_UI_LIST_H + +#include "components/abstract_adapter.h" +#include "components/ui_abstract_scroll.h" +#include "dock/focus_manager.h" +#include "list.h" + +namespace OHOS { +/** + * @brief Represents a listener that contains a callback to be invoked when the scroll state changes or when a new child + * view is selected at the preset position as this list scrolls. The scroll state can be {@link + * SCROLL_STATE_STOP} or {@link SCROLL_STATE_MOVE}. + * @since 1.0 + * @version 1.0 + */ +class ListScrollListener : public HeapBase { +public: + /** + * @brief A constructor used to create a ListScrollListener instance with the default state + * {@link SCROLL_STATE_STOP}. + * @since 1.0 + * @version 1.0 + */ + ListScrollListener() : state_(SCROLL_STATE_STOP) {} + + /** + * @brief A destructor used to delete the ListScrollListener instance. + * @since 1.0 + * @version 1.0 + */ + virtual ~ListScrollListener() {} + + /** + * @brief Called when a scroll starts. + * @param index Indicates the index of the child view being selected at the preset position. This parameter should + * be set to {@link NULL_SELECT_INDEX} if no child view is selected or no position is preset. + * @param view Indicates the child view being selected at the preset position. This parameter should be set to + * NULL if no child view is selected or no position is preset. + * @since 1.0 + * @version 1.0 + */ + virtual void OnScrollStart(int16_t index, UIView* view) {} + + /** + * @brief Called when a scroll ends. + * + * @param index Indicates the index of the child view being selected at the preset position. This parameter should + * be set to {@link NULL_SELECT_INDEX} if no child view is selected or no position is preset. + * @param view Indicates the child view being selected at the preset position. This parameter should be set to + * NULL if no child view is selected or no position is preset. + * @since 1.0 + * @version 1.0 + * + */ + virtual void OnScrollEnd(int16_t index, UIView* view) {} + + /** + * @brief Called when a new child view is selected at the preset position as this list scrolls. For details about + * how to set the position, see {@link SetSelectPosition}. + * + * @param index Indicates the index of the child view being selected at the preset position. This parameter should + * be set to {@link NULL_SELECT_INDEX} if no child view is selected or no position is preset. + * @param view Indicates the child view being selected at the preset position. This parameter should be set to + * NULL if no child view is selected or no position is preset. + * @since 1.0 + * @version 1.0 + * + */ + virtual void OnItemSelected(int16_t index, UIView* view) {} + + /** + * @brief Obtains the scroll state of this list. + * + * @return Returns the scroll state, either {@link SCROLL_STATE_STOP} or {@link SCROLL_STATE_MOVE}. + * @since 1.0 + * @version 1.0 + */ + uint8_t GetScrollState() const + { + return state_; + } + + void SetScrollState(uint8_t state) + { + state_ = state; + } + + static constexpr uint8_t SCROLL_STATE_STOP = 0; + static constexpr uint8_t SCROLL_STATE_MOVE = 1; + +private: + friend class UIList; + uint8_t state_; +}; + +/** + * @brief Represents a scrollable list which is used with the adapter {@link AbstractAdapter} to implement scrolling, + * inertial scrolling, automatic alignment, and invoking of a callback when a child view is selected at the + * preset position as this list scrolls. + * + * You need to override {@link AbstractAdapter} to implement functions for setting and saving data, obtaining data + * quantity, and creating child views. UIList is used when there is a large number of child views with a fixed + * format. This list automatically reclaims the child views removed out of the current view as it scrolls so that as + * many as child views can be displayed with a lower memory consumption. + * + * @since 1.0 + * @version 1.0 + */ +class UIList : public UIAbstractScroll { +public: + /** + * @brief A constructor used to create a UIList instance in the vertical direction. + * @since 1.0 + * @version 1.0 + */ + UIList(); + + /** + * @brief A constructor used to create a UIList instance in the specified direction. + * + * @param direction Indicates the UIList direction, either {@link HORIZONTAL} or {@link VERTICAL}. + * @since 1.0 + * @version 1.0 + */ + UIList(uint8_t direction); + + /** + * @brief A destructor used to delete the UIList instance. + * @since 1.0 + * @version 1.0 + */ + virtual ~UIList(); + + /** + * @brief Obtains the view type. + * @return Returns the view type, as defined in {@link UIViewType}. + * @since 1.0 + * @version 1.0 + */ + UIViewType GetViewType() const override + { + return UI_LIST; + } + + bool OnDragEvent(const DragEvent& event) override; + + bool OnDragEndEvent(const DragEvent& event) override; + + bool OnPressEvent(const PressEvent& event) override; + +#if ENABLE_ROTATE_INPUT + bool OnRotateEvent(const RotateEvent& event) override; +#endif + + /** + * @brief Sets the list direction. + * + * @param direction Indicates the list direction, either {@link HORIZONTAL} or {@link VERTICAL}. + * @since 1.0 + * @version 1.0 + */ + void SetDirection(uint8_t direction) + { + direction_ = direction; + } + + /** + * @brief Obtains the list direction. + * @return Returns the list direction, either {@link HORIZONTAL} or {@link VERTICAL}. + * @since 1.0 + * @version 1.0 + */ + uint8_t GetDirection() const + { + return direction_; + } + + /** + * @brief Sets the adapter for this list. The content of this list is initialized when the adapter is set. + * + * @param adapter Indicates the adapter to set. For details, see {@link AbstractAdapter}. + * @since 1.0 + * @version 1.0 + */ + void SetAdapter(AbstractAdapter* adapter); + + /** + * @brief Moves the position of all child views. + * + * @param offsetX Indicates the offset distance by which a child view is moved on the x-axis. + * @param offsetY Indicates the offset distance by which a child view is moved on the y-axis. + * @since 1.0 + * @version 1.0 + */ + virtual void MoveChildByOffset(int16_t x, int16_t y) override; + + /** + * @brief Scrolls to change the index of the first row or column of the current view. + * + * @param index Indicates the new index of the first row or column of the current view. + * @since 1.0 + * @version 1.0 + */ + void ScrollTo(uint16_t index); + + /** + * @brief Scrolls the content in this list. + * + * @param distance Indicates the distance by which the content is scrolled. + * @since 1.0 + * @version 1.0 + */ + void ScrollBy(int16_t distance); + + /** + * @brief Sets the start index for this list. + * + * @param index Indicates the start index to set. The default value is 0. + * @since 1.0 + * @version 1.0 + * + */ + void SetStartIndex(uint16_t index) + { + startIndex_ = index; + } + + /** + * @brief Obtains the start index of this list. The default value is 0. + * + * @return Returns the start index. + * @since 1.0 + * @version 1.0 + */ + uint16_t GetStartIndex() const + { + return startIndex_; + } + + /** + * @brief Sets the loop state for this list, in which a loop scroll is possible since the top and bottom of the list + * are connected together. + * + * @param state Indicates the loop state to set. + * @since 1.0 + * @version 1.0 + */ + void SetLoopState(bool state) + { + isLoopList_ = state; + } + + /** + * @brief Checks whether this list is in a loop state. + * + * @return Returns if the list is in the loop state; returns false if the list is in the common state. + * @since 1.0 + * @version 1.0 + */ + bool GetLoopState() const + { + return isLoopList_; + } + + /** + * @brief Sets the position where a child view is selected as this list scrolls. + * + * When a child view is selected at the specified position, the callback {@link ListScrollListener} is invoked. + * You can implement the zoom-in and color-change effects in the callback. + * + * @param position Indicates the position to set. The default value is 0, indicating that no position is + * set. + * @since 1.0 + * @version 1.0 + */ + void SetSelectPosition(uint16_t position) + { + selectPosition_ = position; + } + + /** + * @brief Obtains the child view being selected at the preset position. + * + * @return Returns the child view if available; returns NULL if no child view is selected or no position is + * set. + * @since 1.0 + * @version 1.0 + */ + UIView* GetSelectView(); + + /** + * @brief Sets the listener that contains a callback to be invoked when a child view is selected as this list + * scrolls. + * + * @param scrollListener Indicates the listener to set. + * @since 1.0 + * @version 1.0 + */ + void SetScrollStateListener(ListScrollListener* scrollListener) + { + scrollListener_ = scrollListener; + } + + /** + * @brief Refreshes this list. The number of child views in the current view is fixed and the positions of those + * reserved child views as this list scrolls remain unchanged. + * @since 1.0 + * @version 1.0 + */ + void RefreshList(); + + /** + * @brief Sets the automatic alignment state for this list. When a scroll stops, a child view is selected and its + * position is automatically aligned with the preset position. + * + * @param state Indicates the automatic alignment state. true indicates this state is enabled, and + * false indicates the opposite case. + * @since 1.0 + * @version 1.0 + */ + void EnableAutoAlign(bool state) + { + autoAlign_ = state; + } + + void RemoveAll() override; + + static constexpr int8_t NULL_SELECT_INDEX = -1; + + UIView* onSelectedView_; + +protected: + static constexpr int16_t RECALCULATE_DRAG_DISTANCE = 10; + static constexpr int16_t RECALCULATE_DRAG_TIMES = 10; + void StopAnimator() override; + bool DragXInner(int16_t distance) override; + bool DragYInner(int16_t distance) override; + +private: + friend class UIPicker; + class Recycle : public HeapBase { + public: + explicit Recycle(UIList* list) : adapter_(nullptr), listView_(list) {} + virtual ~Recycle(); + void InitRecycle(); + UIView* GetView(int16_t index); + void SetAdapter(AbstractAdapter* adapter) + { + adapter_ = adapter; + } + + void SetList(UIList* listView) + { + listView_ = listView; + } + + void AddScrapView(UIView* view) + { + scrapView_.PushBack(view); + } + + uint16_t GetAdapterItemCount() + { + return (adapter_ == nullptr) ? 0 : adapter_->GetCount(); + } + + void ClearScrapView() + { + scrapView_.Clear(); + } + + private: + void FillActiveView(); + + List scrapView_; + AbstractAdapter* adapter_; + UIList* listView_; + }; + + void PushBack(UIView* view); + void PopItem(UIView* view); + void PushFront(UIView* view); + void SetHead(UIView* view); + bool MoveChildStep(int16_t distance); + bool MoveChildStepInner(int16_t distance, + int16_t (UIView::*pfnGetXOrY)() const, + int16_t (Rect::*pfnGetWidthOrHeight)() const); + uint16_t GetIndexInc(uint16_t index); + uint16_t GetIndexDec(uint16_t index); + + bool MoveOffset(int16_t offset); + bool IsNeedReCalculateDragEnd(); + bool ReCalculateDragEnd(); +#if ENABLE_MOTOR + void SetMotorType(MotorType motorType); + MotorType motorType_; +#endif + bool isLoopList_; + bool isReCalculateDragEnd_; + bool autoAlign_; + uint16_t startIndex_; + uint16_t topIndex_; + uint16_t bottomIndex_; + uint16_t selectPosition_; + int16_t onSelectedIndex_; + Recycle recycle_; + ListScrollListener* scrollListener_; + void CalculateReboundDistance(int16_t& dragDistanceX, int16_t& dragDistanceY) override; +}; +} // namespace OHOS +#endif // GRAPHIC_LITE_UI_LIST_H diff --git a/interfaces/kits/components/ui_picker.h b/interfaces/kits/components/ui_picker.h new file mode 100755 index 0000000..6b248d9 --- /dev/null +++ b/interfaces/kits/components/ui_picker.h @@ -0,0 +1,429 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +/** + * @addtogroup UI_Components + * @{ + * + * @brief Defines UI components such as buttons, texts, images, lists, and progress bars. + * + * @since 1.0 + * @version 1.0 + */ + +/** + * @file ui_picker.h + * + * @brief Defines the attributes and functions of the UIPicker class. + * + * @since 1.0 + * @version 1.0 + */ + +#ifndef UI_PICKER_H +#define UI_PICKER_H + +#include "components/text_adapter.h" +#include "components/ui_list.h" + +namespace OHOS { +/** + * @brief Defines a picker. Multiple texts or numbers can be put into a sliding list for selection. + * The selected text or numbers are highlighted. + * + * @since 1.0 + * @version 1.0 + */ +class UIPicker : public UIViewGroup { +public: + /** + * @brief A constructor used to create a UIPicker instance. + * + * @since 1.0 + * @version 1.0 + */ + UIPicker(); + + /** + * @brief A destructor used to delete the UIPicker instance. + * + * @since 1.0 + * @version 1.0 + */ + virtual ~UIPicker(); + + /** + * @brief Obtains the view type. + * + * @return Returns the view type. For details, see {@link UIViewType}. + * @since 1.0 + * @version 1.0 + */ + UIViewType GetViewType() const override + { + return UI_PICKER; + } + + bool OnPreDraw(Rect& invalidatedArea) const override + { + return false; + } + + /** + * @brief Sets dynamic text data in the picker by using a string array. + * + * @param value[] Indicates the array of text data. + * @param count Indicates the array size. + * @return Returns true if the setting is successful; returns false otherwise. + * @since 1.0 + * @version 1.0 + */ + virtual bool SetValues(const char* value[], uint16_t count); + + /** + * @brief Sets the numeric data in the picker by using a given numeric range. + * + * All integers in the range are automatically generated based on the start value and end value and placed in + * the picker in sequence. The start value must be smaller or equal to the end value. + * + * @param start Indicates the start integer. + * @param end Indicates the end integer. + * @return Returns true if the setting is successful; returns false otherwise. + * @since 1.0 + * @version 1.0 + */ + virtual bool SetValues(int16_t start, int16_t end); + + /** + * @brief Clears all values in the picker. + * + * @since 1.0 + * @version 1.0 + */ + virtual void ClearValues(); + + /** + * @brief Sets the font IDs of dynamic text, which is the string array set through {@link SetValues}. + * + * @param backgroundFontId Indicates the font ID of the background text. + * @param highlightFontId Indicates the font ID of the highlighted text. + * @since 1.0 + * @version 1.0 + */ + void SetFontId(uint8_t backgroundFontId, uint8_t highlightFontId); + + /** + * @brief Sets the font name and size for the background text. + * + * @param name Indicates the pointer to the font name to set. + * @param size Indicates the font size to set. + * @since 1.0 + * @version 1.0 + */ + void SetBackgroundFont(const char* name, uint8_t size); + + /** + * @brief Sets the font name and size for the highlighted text. + * + * @param name Indicates the pointer to the font name to set. + * @param size Indicates the font size to set. + * @since 1.0 + * @version 1.0 + */ + void SetHighlightFont(const char* name, uint8_t size); + + /** + * @brief Obtains the font ID of the background text. + * + * @return Returns the font ID. + * @since 1.0 + * @version 1.0 + */ + uint16_t GetBackgroundFontId() const + { + return backgroundFontId_; + } + + /** + * @brief Obtains the font ID of the highlighted text. + * + * @return Returns the font ID. + * @since 1.0 + * @version 1.0 + */ + uint16_t GetHighlightFontId() const + { + return highlightFontId_; + } + + /** + * @brief Sets the text color. + * + * @param backgroundColor Indicates the color of the background text. + * @param highlightColor Indicates the color of the highlighted text. + * @since 1.0 + * @version 1.0 + */ + void SetTextColor(ColorType backgroundColor, ColorType highlightColor); + + /** + * @brief Obtains the color of the background text. + * + * @return Returns the color. + * @since 1.0 + * @version 1.0 + */ + ColorType GetBackgroundTextColor() const + { + return backgroundColor_; + } + + /** + * @brief Obtains the color of the highlighted text. + * + * @return Returns the color of the highlighted text. + * @since 1.0 + * @version 1.0 + */ + ColorType GetHighlightTextColor() const + { + return highlightColor_; + } + + /** + * @brief Sets the index of the item currently selected in the picker. + * + * @param index Indicates the index to set. + * @return Returns true if the setting is successful; returns false otherwise. + * @since 1.0 + * @version 1.0 + */ + bool SetSelected(uint16_t index); + + /** + * @brief Obtains the index of the item currently selected in the picker. + * + * @return Returns the index. + * @since 1.0 + * @version 1.0 + */ + uint16_t GetSelected() const; + + /** + * @brief Sets the height of each item in the picker. + * + * @param height Indicates the height to set. + * @since 1.0 + * @version 1.0 + */ + void SetItemHeight(int16_t height); + + /** + * @brief Sets the width for this component. + * + * @param width Indicates the width to set. + * @since 1.0 + * @version 1.0 + */ + void SetWidth(int16_t width) override; + + /** + * @brief Sets the height for this component. + * + * @param height Indicates the height to set. + * @since 1.0 + * @version 1.0 + */ + void SetHeight(int16_t height) override; + + /** + * @brief Sets whether a picker can slide cyclically. + * + * @param state Specifies whether the picker can slide cyclically. Value true indicates that the picker + * can slide cyclically, and value false indicates that the picker cannot + * slide cyclically. The default value is false. + * @since 1.0 + * @version 1.0 + */ + void SetLoopState(bool state); + + /** + * @brief Defines the listener used by a picker. This listener is triggered when an item + * is selected after sliding stops. + * + * @since 1.0 + * @version 1.0 + */ + class SelectedListener : public HeapBase { + public: + /** + * @brief A constructor used to create a SelectedListener instance. + * + * @since 1.0 + * @version 1.0 + */ + SelectedListener() {} + + /** + * @brief A destructor used to delete the SelectedListener instance. + * + * @since 1.0 + * @version 1.0 + */ + virtual ~SelectedListener() {} + + /** + * @brief Called when an item is selected after sliding stops. This function is implemented by applications. + * + * @param picker Indicates the picker instance. + * @since 1.0 + * @version 1.0 + */ + virtual void OnPickerStoped(UIPicker& picker) {} + }; + + /** + * @brief Registers a listener for a selected event. + * + * @param pickerListener Indicates the listener for a selected event in the picker. For details, + * see {@link SelectedListener}. + * + * @since 1.0 + * @version 1.0 + */ + void RegisterSelectedListener(SelectedListener* pickerListener) + { + pickerListener_ = pickerListener; + } + + /** + * @brief Sets the text direction. + * + * @param direct Indicates the text direction to set. For details, see {@link UITextLanguageDirect}. + * + * @since 1.0 + * @version 1.0 + */ + void SetDirect(UITextLanguageDirect direct); + + /** + * @brief Sets the text formatter. + * + * @param formatter Indicates the pointer to the text formatter. For details, see {@link TextFormatter}. + * + * @since 1.0 + * @version 1.0 + */ + void SetTextFormatter(TextFormatter* formatter); + +#if ENABLE_ROTATE_INPUT + /** + * @brief 使组件注册获取焦点 + * + * @since 5.0 + * @version 3.0 + */ + void RequestFocus() override + { + list_.RequestFocus(); + } + + /** + * @brief 使组件失去焦点 + * + * @since 5.0 + * @version 3.0 + */ + void ClearFocus() override + { + list_.ClearFocus(); + } + + /** + * @brief 设置组件旋转系数 + * + * @param factor 旋转系数,旋转输入事件的旋转参数与旋转系数的乘积为实际滑动像素值 + * @since 5.0 + * @version 3.0 + */ + void SetRotateFactor(int8_t factor) + { + list_.SetRotateFactor(factor); + } + + /** + * @brief 获得组件旋转系数 + * @return 返回旋转系数 + * + * @since 5.0 + * @version 3.0 + */ + int8_t GetRotateFactor() + { + return list_.GetRotateFactor(); + } +#endif + +protected: + bool RefreshSelected(uint16_t index); + void RefreshList(); + virtual void ClearList(); + virtual void Refresh(); + virtual void InitTextAdapter() + { + if (textAdapter_ == nullptr) { + textAdapter_ = new TextAdapter(); + if (textAdapter_ == nullptr) { + GRAPHIC_LOGE("new TextAdapter fail"); + return; + } + } + } + + bool isWidthSet_ : 1; + bool isHeightSet_ : 1; + TextAdapter* textAdapter_; + uint16_t maxCount_; + uint16_t setSelectedIndex_; + +private: + friend class PickerListScrollListener; + bool RefreshValues(const char* value[], uint16_t count); + bool RefreshValues(int16_t start, int16_t end); + + uint16_t backgroundFontId_; + uint16_t highlightFontId_; + uint8_t backgroundFontSize_; + uint8_t highlightFontSize_; + char* backgroundFontName_; + char* highlightFontName_; + + uint16_t itemsWidth_; + uint16_t itemsHeight_; + const char** rangeValue_; + uint16_t rangeValueCount_; + int16_t startValue_; + int16_t endValue_; + ColorType backgroundColor_; + ColorType highlightColor_; + List dataList_; + bool isSetAdaptered_ : 1; + UIList list_; + void* listListener_; + SelectedListener* pickerListener_; + UITextLanguageDirect direct_; +}; +} // namespace OHOS +#endif diff --git a/interfaces/kits/components/ui_qrcode.h b/interfaces/kits/components/ui_qrcode.h new file mode 100755 index 0000000..5e23a00 --- /dev/null +++ b/interfaces/kits/components/ui_qrcode.h @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +/** + * @addtogroup UI_Components + * @{ + * + * @brief Defines UI components such as buttons, texts, images, lists, and progress bars. + * + * @since 1.0 + * @version 1.0 + */ + +/** + * @file ui_qrcode.h + * + * @brief Declares the attributes and functions of the UIQrcode class. + * + * @since 3.0 + * @version 5.0 + */ + +#ifndef GRAPHIC_LITE_UI_QRCODE_H +#define GRAPHIC_LITE_UI_QRCODE_H + +#include "components/ui_image_view.h" + +namespace qrcodegen { +class QrCode; +} + +namespace OHOS { +/** + * @brief Provides functions related to quick response (QR) codes. + * + * @since 3.0 + * @version 5.0 + */ +class UIQrcode : public UIImageView { +public: + /** + * @brief A default constructor used to create a UIQrcode instance. + * + * @since 3.0 + * @version 5.0 + */ + UIQrcode(); + + /** + * @brief A destructor used to delete the UIQrcode instance. + * + * @since 3.0 + * @version 5.0 + */ + virtual ~UIQrcode(); + + /** + * @brief Sets the QR code information. + * + * @param val Indicates the pointer to the content used to generate the QR code. + * @param backgroundColor Indicates the background color of the QR code. It is white by default. + * @param qrColor Indicates the QR code color. It is black by default. + * @since 3.0 + * @version 5.0 + */ + void SetQrcodeInfo(const char* val, ColorType backgroundColor = Color::White(), ColorType qrColor = Color::Black()); + + /** + * @brief Obtains the view type. + * + * @return Returns the view type. For details, see {@link UIViewType}. + * @since 1.0 + * @version 1.0 + */ + UIViewType GetViewType() const override + { + return UI_QRCODE; + } + + /** + * @brief Sets the QR code width. + * + * @param width Indicates the width to set. + * @since 1.0 + * @version 1.0 + */ + void SetWidth(int16_t width) override; + + /** + * @brief Sets the QR code height. + * + * @param height Indicates the height to set. + * @since 1.0 + * @version 1.0 + */ + void SetHeight(int16_t height) override; + +private: + void ReMeasure() override; + void RefreshQrcode(); + void SetImageInfo(qrcodegen::QrCode& qrcode); + void GenerateQrCode(qrcodegen::QrCode& qrcode); + void FillQrCodeColor(qrcodegen::QrCode& qrcode); + void FillQrCodeBackgroundColor(); + void SetQrcodeVal(const char* val, uint32_t length); + void GetDestData(uint8_t* destData, int32_t outFilePixelPrescaler); + + static constexpr uint8_t QRCODE_FACTOR_NUM = 4; + ImageInfo imageInfo_; + int16_t width_; + bool needDraw_; + ColorType backgroundColor_; + ColorType qrColor_; + char* qrcodeVal_; +}; +} // namespace OHOS +#endif // GRAPHIC_LITE_UI_QRCODE_H diff --git a/interfaces/kits/components/ui_radio_button.h b/interfaces/kits/components/ui_radio_button.h new file mode 100755 index 0000000..0eb7934 --- /dev/null +++ b/interfaces/kits/components/ui_radio_button.h @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +/** + * @addtogroup UI_Components + * @{ + * + * @brief Defines UI components such as buttons, texts, images, lists, and progress bars. + * + * @since 1.0 + * @version 1.0 + */ + +/** + * @file ui_radio_button.h + * + * @brief Defines the attributes and common functions of a radio button. + * + * @since 1.0 + * @version 1.0 + */ + +#ifndef GRAPHIC_LITE_UI_RADIO_BUTTON_H +#define GRAPHIC_LITE_UI_RADIO_BUTTON_H + +#include "components/ui_checkbox.h" + +namespace OHOS { +/** + * @brief Represents a radio button. + * + * Only one option can be selected with the radio button. + * + * @see UICheckBox + * @since 1.0 + * @version 1.0 + */ +class UIRadioButton : public UICheckBox { +public: + /** + * @brief A constructor used to create a UIRadioButton instance. + * + * @since 1.0 + * @version 1.0 + */ + UIRadioButton(); + + /** + * @fn UIRadioButton::UIRadioButton(const char* name); + * + * @brief Default constructor + */ + UIRadioButton(const char* name); + + /** + * @brief A destructor used to delete the UIRadioButton instance. + * + * @since 1.0 + * @version 1.0 + */ + virtual ~UIRadioButton() + { + if (name_ != nullptr) { + UIFree(name_); + name_ = nullptr; + } + } + + /** + * @brief Obtains the component type. + * + * @return Returns the component type, as defined in {@link UIViewType}. + * @since 1.0 + * @version 1.0 + */ + UIViewType GetViewType() const override + { + return UI_RADIO_BUTTON; + } + + bool OnPreDraw(Rect& invalidatedArea) const override + { + return false; + } + + void OnDraw(const Rect& invalidatedArea) override; + + /** + * @fn virtual void UIRadioButton::OnClickEvent(const ClickEvent& event) override; + * + * @brief Executes the click event action + * OnClickEvent will reverse the selected state of checkbox. + * Example: If the check box is selected, the checkbox status is changed to + * Unselected after the click action is taken. + * + * @param event The event that passed when OnClickEvent is invoked. + * @return Returns true if the event is consumed; returns false otherwise. + */ + bool OnClickEvent(const ClickEvent& event) override; + + /** + * @brief Sets the name for this radio button. + * + * @param name Indicates the name to set, which is a character string. + * @since 1.0 + * @version 1.0 + */ + void SetName(const char* name); + + /** + * @brief Obtains the name of this radio button. + * + * @return Returns the name of this radio button, which is a defined character string. Radio buttons sharing the + * same name are in the same batch from which only one can be selected. + * @since 1.0 + * @version 1.0 + */ + const char* GetName() const + { + return name_; + } + +private: + void FindRadioButtonAndChangeState(UIView* view); + static constexpr int16_t DEFAULT_HOT_WIDTH = 46; + static constexpr int16_t DEFAULT_HOT_HEIGHT = 46; + static constexpr int16_t DEFAULT_RADIUS_BIG = 11; + static constexpr int16_t DEFAULT_RADIUS_SMALL = 6; + static constexpr int16_t DEFAULT_LINE_WIDTH = 1; + + char* name_; + int16_t width_; + int16_t height_; + uint16_t radiusBig_; + uint16_t radiusSmall_; + int16_t lineWidth_; + + void CalculateSize(); +}; +} // namespace OHOS +#endif // GRAPHIC_LITE_UI_RADIO_BUTTON_H diff --git a/interfaces/kits/components/ui_repeat_button.h b/interfaces/kits/components/ui_repeat_button.h new file mode 100755 index 0000000..83e4e1a --- /dev/null +++ b/interfaces/kits/components/ui_repeat_button.h @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +/** + * @addtogroup UI_Components + * @{ + * + * @brief Defines UI components such as buttons, texts, images, lists, and progress bars. + * + * @since 1.0 + * @version 1.0 + */ + +/** + * @file ui_repeate_button.h + * + * @brief Defines the attributes and common functions of a repeat button. + * + * If a repeat button is clicked and hold, the click event is triggered continuously. + * + * @since 1.0 + * @version 1.0 + */ + +#ifndef GRAPHIC_LITE_UI_REPEAT_BUTTON_H +#define GRAPHIC_LITE_UI_REPEAT_BUTTON_H + +#include "components/ui_button.h" + +namespace OHOS { +/** + * @brief Represents a repeat button. + * + * If a repeat button is clicked and hold, the click event is triggered continuously. + * + * @see UIButton + * @since 1.0 + * @version 1.0 */ +class UIRepeatButton : public UIButton { +public: + /** + * @brief A constructor used to create a UIRepeatButton instance. + * + * @since 1.0 + * @version 1.0 + */ + UIRepeatButton(); + + /** + * @brief A destructor used to delete the UIRepeatButton instance. + * + * @since 1.0 + * @version 1.0 + */ + virtual ~UIRepeatButton(); + + /** + * @brief Obtains the component type. + * + * @return Returns the component type, as defined in {@link UIViewType}. + * @since 1.0 + * @version 1.0 + */ + UIViewType GetViewType() const override + { + return UI_REPEAT_BUTTON; + } + + /** + * @brief Sets the interval between two consecutive click events. + * + * @param interval Indicates the interval to set. + + * @since 1.0 + * @version 1.0 + */ + virtual void SetInterval(uint16_t interval) + { + ticksInterval_ = interval; + } + + /** + * @brief Obtains the interval between two consecutive click events. + * + * @return Returns the interval between two consecutive click events. + * @since 1.0 + * @version 1.0 + */ + virtual uint16_t GetInterval() const + { + return ticksInterval_; + } + + /** + * @fn void UIRepeatButton::OnClickEvent(const ClickEvent& event) + * + * @brief The action of click event. + * + * @param [in] event click event. + * @return Returns true if the event is consumed; returns false otherwise. + */ + virtual bool OnClickEvent(const ClickEvent& event) override; + + /** + * @fn void UIRepeatButton::OnReleaseEvent(const ReleaseEvent& event) + * + * @brief The action of release event. + * + * @param [in] event release event. + */ + virtual bool OnReleaseEvent(const ReleaseEvent& event) override; + + /** + * @fn void UIRepeatButton::OnLongPressEvent(const ReleaseEvent& event) + * + * @brief The action of long press event. + * + * @param [in] event long press event. + */ + virtual bool OnLongPressEvent(const LongPressEvent& event) override; + + /** + * @fn void UIRepeatButton::HandleTickEvent() + * + * @brief handle the event of long pressing. + */ + void HandleTickEvent(); + +private: + uint16_t ticksInterval_; + ClickEvent event_; + bool longPressed_; + static UIRepeatButton* repeatButton_; + uint32_t timerRepeatID_; + + virtual void OnDraw(const Rect& invalidatedArea) override; + inline void SetEvent(const ClickEvent& event); +}; +} // namespace OHOS + +#endif // GRAPHIC_LITE_UI_REPEAT_BUTTON_H diff --git a/interfaces/kits/components/ui_scroll_view.h b/interfaces/kits/components/ui_scroll_view.h new file mode 100755 index 0000000..6785d6d --- /dev/null +++ b/interfaces/kits/components/ui_scroll_view.h @@ -0,0 +1,297 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +/** + * @addtogroup UI_Components + * @{ + * + * @brief Defines UI components such as buttons, texts, images, lists, and progress bars. + * + * @since 1.0 + * @version 1.0 + */ + +/** + * @file ui_scroll_view.h + * + * @brief Declares a view group that allows its child views to be displayed as scroll events occur. + * + * @since 1.0 + * @version 1.0 + */ + +#ifndef GRAPHIC_LITE_UI_SCROLL_VIEW_H +#define GRAPHIC_LITE_UI_SCROLL_VIEW_H + +#include "animator/animator.h" +#include "components/ui_abstract_scroll.h" + +namespace OHOS { +/** + * @brief Supports horizontal or vertical scroll of child views. This class is inherited from {@link UIAbstractScroll}. + * + * Horizontal or vertical scroll occurs only when the width or height of the child view is greater than that of the + * UIScrollView. + * + * @since 1.0 + * @version 1.0 + */ +class UIScrollView : public UIAbstractScroll { +public: + /** + * @brief Represents a listener that contains a callback to be invoked upon scroll state changes. The state can + * either be {@link SCROLL_STATE_STOP} or {@link SCROLL_STATE_MOVE}. + * @since 1.0 + * @version 1.0 + */ + class OnScrollListener : public HeapBase { + public: + /** + * @brief A constructor used to create an OnScrollListener instance with the default scroll state + * {@link SCROLL_STATE_STOP}. + * @since 1.0 + * @version 1.0 + */ + OnScrollListener() : state_(SCROLL_STATE_STOP) {} + + /** + * @brief A destructor used to delete the OnScrollListener instance. + * @since 1.0 + * @version 1.0 + */ + virtual ~OnScrollListener() {} + + /** + * @brief Called when a scroll starts. + * + * @since 1.0 + * @version 1.0 + */ + virtual void OnScrollStart() {} + + /** + * @brief Called when a scroll ends. + * + * @since 1.0 + * @version 1.0 + */ + virtual void OnScrollEnd() {} + + /** + * @brief Obtains the scroll state of this view. + * + * @return Returns the scroll state, either {@link SCROLL_STATE_STOP} or {@link SCROLL_STATE_MOVE}. + * @since 1.0 + * @version 1.0 + */ + uint8_t GetScrollState() const + { + return state_; + } + + void SetScrollState(uint8_t state) + { + state_ = state; + } + + static constexpr uint8_t SCROLL_STATE_STOP = 0; + static constexpr uint8_t SCROLL_STATE_MOVE = 1; + + private: + uint8_t state_; + }; + + /** + * @brief A constructor used to create a UIScrollView instance, with both horizontal and vertical scrolls + * supported. + * + * @since 1.0 + * @version 1.0 + */ + UIScrollView(); + + /** + * @brief A destructor used to delete the UIScrollView instance. + * + * @since 1.0 + * @version 1.0 + */ + virtual ~UIScrollView() {} + + /** + * @brief Obtains the view type. + * @return Returns the view type, as defined in {@link UIViewType}. + * + * @since 1.0 + * @version 1.0 + */ + UIViewType GetViewType() const override + { + return UI_SCROLL_VIEW; + } + +#if ENABLE_ROTATE_INPUT + bool OnRotateEvent(const RotateEvent& event) override; +#endif + + void OnPostDraw(const Rect& invalidatedArea) override; + + bool OnDragEvent(const DragEvent& event) override; + + bool OnDragEndEvent(const DragEvent& event) override; + + bool OnPressEvent(const PressEvent& event) override; + + /** + * @brief Scrolls the content of this view. + * + * @param xDistance Indicates the offset distance by which the content is scrolled on the x-axis. + * @param yDistance Indicates the offset distance by which the content is scrolled on the y-axis. + * @since 1.0 + * @version 1.0 + */ + void ScrollBy(int16_t xDistance, int16_t yDistance); + + /** + * @brief Sets the width for this scroll bar. + * + * @param width Indicates the width to set. The default value is {@link DEFAULT_BAR_WIDTH}. + * @since 1.0 + * @version 1.0 + */ + void SetScrollbarWidth(uint8_t width) + { + scrollBarWidth_ = width; + minScrollBarLen_ = scrollBarWidth_ * MIN_BAR_MULTIPLE; + } + + /** + * @brief Sets whether a horizontal scroll is enabled. + * + * @param state Specifies whether a horizontal scroll is enabled. true indicates a horizontal scroll is + * enabled, and false indicates the opposite case. + * @since 1.0 + * @version 1.0 + */ + void SetHorizontalScrollState(bool state) + { + xScrollable_ = state; + } + + /** + * @brief Checks whether a horizontal scroll is enabled. + * + * @return Returns true if a horizontal scroll is enabled; returns false otherwise. + * @since 1.0 + * @version 1.0 + */ + bool GetHorizontalScrollState() const + { + return xScrollable_; + } + + /** + * @brief Sets whether a vertical scroll is enabled. + * + * @param state Specifies whether a vertical scroll is enabled. true indicates a vertical scroll is enabled, + * and false indicates the opposite case. + * @since 1.0 + * @version 1.0 + */ + void SetVerticalScrollState(bool state) + { + yScrollable_ = state; + } + + /** + * @brief Checks whether a vertical scroll is enabled. + * + * @return Returns true if a vertical scroll is enabled, returns false otherwise. + * @since 1.0 + * @version 1.0 + */ + bool GetVerticalScrollState() const + { + return yScrollable_; + } + + /** + * @brief Sets whether the horizontal scroll bar is visible. + * + * @param state Specifies whether the horizontal scroll bar is visible. true indicates the horizontal scroll + * bar is visible, and false indicates the opposite case. + * @since 1.0 + * @version 1.0 + */ + void SetXScrollBarVisible(bool state) + { + xSlider_.SetVisible(state); + } + + /** + * @brief Sets whether the vertical scroll bar is visible. + * + * @param state Specifies whether this vertical scroll bar is visible. true indicates the horizontal scroll + * bar is visible, and false indicates the opposite case. + * @since 1.0 + * @version 1.0 + */ + void SetYScrollBarVisible(bool state) + { + ySlider_.SetVisible(state); + } + + /** + * @brief Registers a listener that contains a callback to be invoked upon scroll state changes. + * + * @param scrollListener Indicates the listener to register. For details, see {@link OnScrollListener}. + * @since 1.0 + * @version 1.0 + */ + void RegisterScrollListener(OnScrollListener* scrollListener) + { + scrollListener_ = scrollListener; + } + + void RefreshScrollBar(); + +protected: + void StopAnimator() override; + bool DragXInner(int16_t distance) override; + bool DragYInner(int16_t distance) override; + +private: + void Drag(const DragEvent& event); + void RefreshScrollBarPosition(); + bool MoveOffset(int16_t offsetX, int16_t offsetY); + int16_t GetXScrollOffset(const Rect& childRect); + int16_t GetYScrollOffset(const Rect& childRect); + void OnChildChanged() override; + void CalculateReboundDistance(int16_t& dragDistanceX, int16_t& dragDistanceY) override; + static constexpr uint8_t DEFAULT_BAR_WIDTH = 5; + static constexpr uint8_t MIN_BAR_MULTIPLE = 2; + static constexpr uint8_t DEFAULT_MIN_BAR_LEN = DEFAULT_BAR_WIDTH * MIN_BAR_MULTIPLE; + UIView xSlider_; + UIView ySlider_; + Point xSliderPos_; + Point ySliderPos_; + int16_t scrollBarWidth_; + bool xScrollable_; + bool yScrollable_; + int16_t minScrollBarLen_; + OnScrollListener* scrollListener_; +}; +} // namespace OHOS +#endif // GRAPHIC_LITE_UI_SCROLL_VIEW_H diff --git a/interfaces/kits/components/ui_slider.h b/interfaces/kits/components/ui_slider.h new file mode 100755 index 0000000..0261dd1 --- /dev/null +++ b/interfaces/kits/components/ui_slider.h @@ -0,0 +1,311 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +/** + * @addtogroup UI_Components + * @{ + * + * @brief Defines UI components such as buttons, texts, images, lists, and progress bars. + * + * @since 1.0 + * @version 1.0 + */ + +/** + * @file ui_slider.h + * + * @brief Defines the attributes and common functions of a slider. + * + * @since 1.0 + * @version 1.0 + */ + +#ifndef GRAPHIC_LITE_UI_SLIDER_H +#define GRAPHIC_LITE_UI_SLIDER_H + +#include "common/image.h" +#include "components/ui_box_progress.h" + +namespace OHOS { +/** + * @brief Represents a slider. + * + * Users can drag or click the knob to adjust the progress of an event. + * + * @see UIBoxProgress + * @since 1.0 + * @version 1.0 + */ +class UISlider : public UIBoxProgress { +public: + /** + * @brief A constructor used to create a UISlider instance. + * + * @since 1.0 + * @version 1.0 + */ + UISlider(); + + /** + * @brief A destructor used to delete the UISlider instance. + * + * @since 1.0 + * @version 1.0 + */ + virtual ~UISlider(); + + /** + * @brief Obtains the view type. + * + * @return Returns the view type, as defined in {@link UIViewType}. + * @since 1.0 + * @version 1.0 + */ + UIViewType GetViewType() const override + { + return UI_SLIDER; + } + + /** + * @brief Sets the width for this knob. + * + * The width of this knob is the same as its height. \n + * By default, the width of this knob is the same as the height of the horizontal slider + * or the width of the vertical slider. \n + * + * @param width Indicates the knob width to set. + * @see GetKnobWidth + * @since 1.0 + * @version 1.0 + */ + void SetKnobWidth(int16_t width) + { + knobWidth_ = width; + knobWidthSetFlag_ = true; + } + + /** + * @brief Obtains the knob width. + * + * @return Returns the knob width. + * @see SetKnobWidth + * @since 1.0 + * @version 1.0 + */ + int16_t GetKnobWidth(); + +#if ENABLE_ROTATE_INPUT + /** + * @brief תϵ + * @return תϵ + * @since 5.0 + * @version 3.0 + */ + int8_t GetRotateFactor() + { + return rotateFactor_; + } + + /** + * @brief תϵ + * @param factor תϵ + * @since 5.0 + * @version 3.0 + */ + void SetRotateFactor(int8_t factor) + { + rotateFactor_ = factor; + } + + bool OnRotateEvent(const RotateEvent& event) override; +#endif + + /** + * @brief Sets the images as pixel maps for this slider, including the background, foreground, and knob images. + * + * @param backgroundImage Indicates the background image to set. + * @param foregroundImage Indicates the foreground image to set. + * @param knobImage Indicates the knob image to set. + * @since 1.0 + * @version 1.0 + */ + void SetImage(const ImageInfo* backgroundImage, const ImageInfo* foregroundImage, const ImageInfo* knobImage); + + /** + * @brief Sets the images for this slider, including the background, foreground, and knob images. + * + * @param backgroundImage Indicates the background image to set. + * @param foregroundImage Indicates the foreground image to set. + * @param knobImage Indicates the knob image to set. + * @since 1.0 + * @version 1.0 + */ + void SetImage(const char* backgroundImage, const char* foregroundImage, const char* knobImage); + + /** + * @brief Sets the colors for this slider, including the background, foreground, and knob colors. + * + * @param backgroundColor Indicates the background color to set. + * @param foregroundColor Indicates the foreground color to set. + * @param knobColor Indicates the knob color to set. + * @since 1.0 + * @version 1.0 + */ + void SetSliderColor(const ColorType backgroundColor, const ColorType foregroundColor, const ColorType knobColor) + { + SetBackgroundStyle(STYLE_BACKGROUND_COLOR, backgroundColor.full); + SetForegroundStyle(STYLE_BACKGROUND_COLOR, foregroundColor.full); + SetKnobStyle(STYLE_BACKGROUND_COLOR, knobColor.full); + } + + /** + * @brief Sets the corner radiuses for this slider, including the background, foreground, and knob corner radiuses. + * + * @param backgroundRadius Indicates the background corner radius to set. + * @param foregroundRadius Indicates the foreground corner radius to set. + * @param knobRadius Indicates the knob corner radius to set. + * @since 1.0 + * @version 1.0 + */ + void SetSliderRadius(int16_t backgroundRadius, int16_t foregroundRadius, int16_t knobRadius) + { + SetBackgroundStyle(STYLE_BORDER_RADIUS, backgroundRadius); + SetForegroundStyle(STYLE_BORDER_RADIUS, foregroundRadius); + SetKnobStyle(STYLE_BORDER_RADIUS, knobRadius); + } + + /** + * @brief Sets the knob style. + * + * @param style Indicates the knob style to set. For details, see {@link Style}. + * @see GetKnobStyle + * @since 1.0 + * @version 1.0 + */ + void SetKnobStyle(const Style& style); + + /** + * @brief Sets a knob style. + * + * @param key Indicates the key of the style to set. + * @param value Indicates the value matching the key. + * @since 1.0 + * @version 1.0 + */ + void SetKnobStyle(uint8_t key, int64_t value); + + /** + * @brief Obtains the knob style. + * + * @return Returns the knob style. + * @since 1.0 + * @version 1.0 + */ + const Style& GetKnobStyle() const; + + /** + * @brief Obtains the value of a knob style. + * + * @param key Indicates the key of the style. + * @return Returns the value of the style. + * @since 1.0 + * @version 1.0 + */ + int64_t GetKnobStyle(uint8_t key) const; + + bool OnClickEvent(const ClickEvent& event) override; + + bool OnDragEvent(const DragEvent& event) override; + + bool OnDragEndEvent(const DragEvent& event) override; + + bool OnPreDraw(Rect& invalidatedArea) const override + { + return false; + } + + void OnDraw(const Rect& invalidatedArea) override; + + /** + * @brief Represents the listener for a slider change. + * + * This is an inner class of UISlider used to listen for slider events and invoke the callback function. + * + * @see UISlider + * @since 1.0 + * @version 1.0 + */ + class UISliderEventListener : public HeapBase { + public: + /** + * @brief A destructor used to delete the UISliderEventListener instance. + * + * @since 1.0 + * @version 1.0 + */ + virtual ~UISliderEventListener() {} + /** + * @brief Called when the slider is dragged or clicked. This is a virtual function, which needs your + * implementation. + * + * @param value Indicates the current value of the slider. + * @since 1.0 + * @version 1.0 + */ + virtual void OnChange(int32_t value) {} + /** + * @brief Called when the slider is released. This is a virtual function, which needs your implementation. + * + * @param value Indicates the current value of the slider. + * @since 1.0 + * @version 1.0 + */ + virtual void OnRelease(int32_t value) {} + }; + + /** + * @brief Sets the listener for a slider change. + * + * When a user drags or clicks the slider, listening is triggered and the OnChange callback is invoked. + * When a user releases the slider, the OnRelease callback is invoked. + * + * @param listener Indicates the listener to set. For details, see {@link UISliderEventListener}. + * @since 1.0 + * @version 1.0 + */ + void SetSliderEventListener(UISliderEventListener* listener) + { + listener_ = listener; + } + +protected: + bool InitImage() override; + +private: + void DrawKnob(const Rect& invalidatedArea, const Rect& foregroundRect); + int32_t CalculateCurrentValue(int16_t length, int16_t totalLength); + int32_t UpdateCurrentValue(const Point& knobPosition); +#if ENABLE_ROTATE_INPUT + int8_t rotateFactor_ = 1; +#endif + int16_t knobWidth_; + bool knobWidthSetFlag_; + bool knobStyleAllocFlag_; + Style* knobStyle_; + Image* knobImage_; + UISliderEventListener* listener_; +}; // class UISlider +} // namespace OHOS +#endif // GRAPHIC_LITE_UI_SLIDER_H diff --git a/interfaces/kits/components/ui_surface_view.h b/interfaces/kits/components/ui_surface_view.h new file mode 100755 index 0000000..9a49d29 --- /dev/null +++ b/interfaces/kits/components/ui_surface_view.h @@ -0,0 +1,176 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef GRAPHIC_LITE_UI_SURFACE_VIEW_H +#define GRAPHIC_LITE_UI_SURFACE_VIEW_H + +/** + * @addtogroup UI_Components + * @{ + * + * @brief Defines UI components such as buttons, texts, images, lists, and progress bars. + * + * @since 1.0 + * @version 1.0 + */ + +/** + * @file ui_surface_view.h + * + * @brief Declares the surface view that interacts with the multimedia to achieve camera preview and video playback. + * + * @since 1.0 + * @version 1.0 + */ + +#include "components/ui_view.h" +#include "surface.h" + +#include + +namespace OHOS { +/** + * @brief Represents a surface view that interacts with the multimedia to achieve camera preview and video playback. + * + * @since 1.0 + * @version 1.0 + */ +class UISurfaceView : public UIView { +public: + /** + * @brief A constructor used to create a UISurfaceView instance. + * + * @since 1.0 + * @version 1.0 + */ + UISurfaceView(); + + /** + * @brief A destructor used to delete the UISurfaceView instance. + * + * @since 1.0 + * @version 1.0 + */ + ~UISurfaceView(); + + /** + * @brief Obtains the surface, which should be used together with the camera and video modules. + * + * @return Returns the surface. + * @since 1.0 + * @version 1.0 + */ + Surface* GetSurface() const; + + /** + * @brief Sets the position for this view. + * + * @param x Indicates the x-coordinate to set. + * @param y Indicates the y-coordinate to set. + * @since 1.0 + * @version 1.0 + */ + void SetPosition(int16_t x, int16_t y) override; + + /** + * @brief Sets the position and size for this view. + * + * @param x Indicates the x-coordinate to set. + * @param y Indicates the y-coordinate to set. + * @param width Indicates the width to set. + * @param height Indicates the height to set. + * @since 1.0 + * @version 1.0 + */ + void SetPosition(int16_t x, int16_t y, int16_t width, int16_t height) override; + + /** + * @brief Adjusts the size of this view. + * + * @param width Indicates the new width. + * @param height Indicates the new height. + * @since 1.0 + * @version 1.0 + */ + void Resize(int16_t width, int16_t height) override; + + /** + * @brief Sets the x-coordinate for this view. + * + * @param x Indicates the x-coordinate to set. + * @since 1.0 + * @version 1.0 + */ + void SetX(int16_t x) override; + + /** + * @brief Sets the y-coordinate for this view. + * + * @param y Indicates the y-coordinate to set. + * @since 1.0 + * @version 1.0 + */ + void SetY(int16_t y) override; + + /** + * @brief Sets the width for this view. + * + * @param width Indicates the width to set. + * @since 1.0 + * @version 1.0 + */ + void SetWidth(int16_t width) override; + + /** + * @brief Sets the height for this view. + * + * @param height Indicates the height to set. + * @since 1.0 + * @version 1.0 + */ + void SetHeight(int16_t height) override; + + /** + * @brief Called before this view is drawn. This function is used to check whether the parent view of this view + * needs to be redrawn so that the drawing process is optimized. + * + * @param invalidatedArea Indicates the area to draw. + * @return Returns true if the parent view needs to be redrawn; returns false otherwise. + * @since 1.0 + * @version 1.0 + */ + bool OnPreDraw(Rect& invalidatedArea) const override; + + /** + * @brief Called when this view is drawn. + * + * @param invalidatedArea Indicates the area to draw. + * @since 1.0 + * @version 1.0 + */ + void OnDraw(const Rect& invalidatedArea) override; + +private: + void Draw(const Rect& invalidatedArea); + + Surface* surface_; + const std::string REGION_POSITION_X = "region_position_x"; + const std::string REGION_POSITION_Y = "region_position_y"; + const std::string REGION_WIDTH = "region_width"; + const std::string REGION_HEIGHT = "region_height"; + const uint8_t DEFAULT_QUEUE_SIZE = 2; +}; +} // namespace OHOS +#endif // GRAPHIC_LITE_UI_SURFACE_VIEW_H diff --git a/interfaces/kits/components/ui_swipe_view.h b/interfaces/kits/components/ui_swipe_view.h new file mode 100755 index 0000000..990b3b6 --- /dev/null +++ b/interfaces/kits/components/ui_swipe_view.h @@ -0,0 +1,368 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +/** + * @addtogroup UI_Components + * @{ + * + * @brief Defines UI components such as buttons, texts, images, lists, and progress bars. + * + * @since 1.0 + * @version 1.0 + */ + +/** + * @file ui_swipe_view.h + * + * @brief Defines the attributes and common functions of a swipe view. + * + * Each swipe view consists of multiple child views, which can be navigated through swiping. The child views can be + * either horizontal or vertical. + * + * @since 1.0 + * @version 1.0 + */ + +#ifndef GRAPHIC_LITE_UI_SWIPE_VIEW_H +#define GRAPHIC_LITE_UI_SWIPE_VIEW_H + +#include "animator/animator.h" +#include "components/ui_abstract_scroll.h" + +namespace OHOS { +/** + * @brief Represents a swipe view. + * + * Each swipe view consists of multiple child views, which can be navigated through swiping. The child views can be + * either horizontal or vertical. + * + * @see UIAbstractScroll + * @since 1.0 + * @version 1.0 + */ +class UISwipeView : public UIAbstractScroll { +public: + /** + * @brief Represents a listener for changes of the swipe view. + * + * This is an inner class of UISwipeView. It contains a callback function to be invoked when the swipe view + * state changes. + * + * @since 1.0 + * @version 1.0 + */ + class OnSwipeListener : public HeapBase { + public: + virtual void OnSwipe(UISwipeView& view) = 0; + virtual ~OnSwipeListener() {} + }; + + enum AlignMode : uint8_t { + ALIGN_LEFT, + ALIGN_CENTER, + ALIGN_RIGHT + }; + + /** + * @brief A constructor used to create a UISwipeView instance. + * + * @since 1.0 + * @version 1.0 + */ + UISwipeView(uint8_t direction = HORIZONTAL); + + /** + * @brief A destructor used to delete the UISwipeView instance. + * + * @since 1.0 + * @version 1.0 + */ + virtual ~UISwipeView(); + + /** + * @brief Obtains the component type. + * + * @return Returns the component type, as defined in {@link UIViewType}. + * @since 1.0 + * @version 1.0 + */ + UIViewType GetViewType() const override + { + return UI_SWIPE_VIEW; + } + + /** + * @brief Sets the dragging direction. + * + * @param direction Indicates the dragging direction, either {@link HORIZONTAL} or {@link VERTICAL}. + * @since 1.0 + * @version 1.0 + */ + void SetDirection(uint8_t direction) + { + direction_ = direction; + } + + /** + * @brief Obtains the dragging direction. + * + * @return Returns the dragging direction. + * @since 1.0 + * @version 1.0 + */ + uint8_t GetDirection() const + { + return direction_; + } + + /** + * @brief Adds a view. + * + * @param view Indicates the view to add. + * @since 1.0 + * @version 1.0 + */ + void Add(UIView* view) override; + + /** + * @brief Inserts a view. + * + * @param prevView Indicates the previous view. + * @param insertView Indicates the view to insert. + * @since 1.0 + * @version 1.0 + */ + void Insert(UIView* prevView, UIView* insertView) override; + + /** + * @brief Deletes a view. + * + * @param view Indicates the view to delete. + * @since 1.0 + * @version 1.0 + */ + virtual void Remove(UIView* view) override; + + /** + * @brief Sets the index for the current tab. + * + * @param index Indicates the index of a view. + * @param needAnimator Specifies whether a flip animation is needed. false (default value) indicates a flip + * animation is not needed, and true indicates the opposite case. + * @since 1.0 + * @version 1.0 + */ + void SetCurrentPage(uint16_t index, bool needAnimator = false); + + /** + * @brief Obtains the current tab index. + * + * @return Returns the current tab index. + * @since 1.0 + * @version 1.0 + */ + uint16_t GetCurrentPage() const + { + return curIndex_; + } + + /** + * @brief Obtains the current view. + * + * @return Returns the current view. + * @since 1.0 + * @version 1.0 + */ + UIView* GetCurrentView() const + { + return curView_; + } + + /** + * @brief Sets a blank size, as defined in {@link DEFAULT_BLANK_SIZE} + * + * @param size Indicates the blank size to set. + * @since 1.0 + * @version 1.0 + */ + void SetBlankSize(uint16_t size) + { + blankSize_ = size; + } + + /** + * @fn void OnDragEvent(const DragEvent& event) override + * + * @brief revice drag event, Switch to specified view when drag + * + * @param event The drag event + */ + bool OnDragEvent(const DragEvent& event) override; + + bool OnDragEndEvent(const DragEvent& event) override; + +#if ENABLE_ROTATE_INPUT + bool OnRotateEvent(const RotateEvent& event) override; +#endif + + /** + * @brief Sets the time for the page being animated. The page will go beyond the blank during this time. + * + * @param time Indicates the time of the page being animated. + * @since 1.0 + * @version 1.0 + */ + void SetAnimatorTime(uint16_t time); + + /** + * @brief Sets whether the swipe view supports a cycle swipe. + * + * @param loop Indicates the cycle swipe flag. true indicates the cycle swipe is supported, and false + * indicates the opposite case. + * @since 1.0 + * @version 1.0 + */ + void SetLoopState(bool loop) + { + loop_ = loop; + } + + /** + * @brief Obtains a view based on its index. + * + * @param Indicates the index of a view. + * @return Returns the view. + * @since 1.0 + * @version 1.0 + */ + UIView* GetViewByIndex(uint16_t index) const; + + /** + * @brief Obtains the listener set for swipe events. + * + * @return Returns the swipe event listener. + * @since 1.0 + * @version 1.0 + */ + OnSwipeListener*& GetOnSwipeListener() + { + return swipeListener_; + } + + /** + * @brief Sets the listener that contains a callback to be invoked upon a swipe event. + * + * @param onSwipeListener Indicates the listener to set. + * @since 1.0 + * @version 1.0 + */ + void SetOnSwipeListener(OnSwipeListener* onSwipeListener) + { + swipeListener_ = onSwipeListener; + } + + /** + * @brief Sets the alignment mode for child components of UISwipeView. + * + * @param alignMode Indicates the alignment mode to set, as enumerated in {@link AlignMode}. + * The default value is ALIGN_CENTER. + * @since 1.0 + * @version 1.0 + */ + void SetAlignMode(AlignMode alignMode = ALIGN_CENTER) + { + alignMode_ = alignMode; + } + + /** + * @brief Obtains the alignment mode of child components of UISwipeView. + * + * @return Returns the alignment mode. For details, see {@link AlignMode}. + * @since 1.0 + * @version 1.0 + */ + AlignMode GetAlignMode() + { + return alignMode_; + } + + /** + * @brief Indicates the horizontal direction. + * + * @since 1.0 + * @version 1.0 + */ + static constexpr uint8_t HORIZONTAL = 0; + + /** + * @brief Indicates the vertical direction. + * + * @since 1.0 + * @version 1.0 + */ + static constexpr uint8_t VERTICAL = 1; + +protected: + bool DragXInner(int16_t distance) override; + bool DragYInner(int16_t distance) override; + void SortChild(); + void StopAnimator() override; + virtual void SwitchToPage(int16_t dst, bool needAnimator = true); + void MoveChildByOffset(int16_t xOffset, int16_t yOffset) override; + + /** + * @brief Indicates that the animation duration is 12 ticks. + * + * @since 1.0 + * @version 1.0 + */ + constexpr static uint16_t ANIMATOR_TIME = 12; + + /** + * @brief Indicates the maximum distance of an invalid dragging. Dragging is not triggered if the distance is less + * than this value. + * + * @since 1.0 + * @version 1.0 + */ + constexpr static uint16_t STOP_DISTANCE = 5; + + /** + * @brief Indicates the maximum distance between the first and the last tab when the current view is not in a cycle + * swipe mode. The page can be rebound after the setting. + * + * @since 1.0 + * @version 1.0 + */ + constexpr static uint16_t DEFAULT_BLANK_SIZE = 30; + uint16_t tickTime_; + OnSwipeListener* swipeListener_; + uint16_t curIndex_; + uint16_t blankSize_; + UIView* curView_; + AlignMode alignMode_ = ALIGN_CENTER; + bool loop_; + +private: + void RefreshCurrentView(int16_t distance); + void RefreshCurrentViewInner(int16_t distance, int16_t (UIView::*pfnGetXOrY)() const, + int16_t(UIView::*pfnGetWidthOrHeight)()); + bool isNeedLoop(); + void MoveFirstChildToLast(); + void MoveLastChildToFirst(); + void CalculateInvalidate(); +}; +} // namespace OHOS +#endif // GRAPHIC_LITE_UI_SWIPE_VIEW_H diff --git a/interfaces/kits/components/ui_texture_mapper.h b/interfaces/kits/components/ui_texture_mapper.h new file mode 100755 index 0000000..460aa5f --- /dev/null +++ b/interfaces/kits/components/ui_texture_mapper.h @@ -0,0 +1,291 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +/** + * @addtogroup UI_Components + * @{ + * + * @brief Defines UI components such as buttons, texts, images, lists, and progress bars. + * + * @since 1.0 + * @version 1.0 + */ + +/** + * @file ui_texture_mapper.h + * + * @brief Defines the attributes and functions of a texture mapper. + * + * @since 1.0 + * @version 1.0 + */ + +#ifndef GRAPHIC_LITE_UI_TEXTURE_MAPPER_H +#define GRAPHIC_LITE_UI_TEXTURE_MAPPER_H + +#include "components/ui_image_view.h" +#include "animator/animator.h" +#include "animator/easing_equation.h" + +namespace OHOS { +/** + * @brief Rotates and scales images. + * + * @see UIImageView + * @since 1.0 + * @version 1.0 + */ +class UITextureMapper : public UIImageView { +public: + /** + * @brief A constructor used to create a UITextureMapper instance. + * + * @since 1.0 + * @version 1.0 + */ + UITextureMapper(); + + /** + * @brief A destructor used to delete the UITextureMapper instance. + * + * @since 1.0 + * @version 1.0 + */ + virtual ~UITextureMapper(); + + /** + * @brief Obtains the view type. + * + * @return Returns the view type, as defined in {@link UIViewType}. + * @since 1.0 + * @version 1.0 + */ + UIViewType GetViewType() const override + { + return UI_TEXTURE_MAPPER; + } + + /** + * @brief Starts this animator. + * + * @since 1.0 + * @version 1.0 + */ + void Start(); + + /** + * @brief Sets the start angle of rotation for this image. + * + * By default, the image starts to rotate from the current angle of this stopped animator. + * + * @param start Indicates the start angle to set. The default value is 0. + * @since 1.0 + * @version 1.0 + */ + void SetRotateStart(int16_t start) + { + rotateCur_ = start; + } + + /** + * @brief Sets the end angle of rotation for this image. + * + * @param end Indicates the end angle of rotation to set. The default value is 0. + * @since 1.0 + * @version 1.0 + */ + void SetRotateEnd(int16_t end) + { + rotateEnd_ = end; + } + + /** + * @brief Sets the start ratio for scaling this image. + * + * By default, the image starts to scale from the current ratio of this stopped animator. \n + * The X and Y directions are scaled at the same ratio. Single-direction scaling is not supported. \n + * + * @param start Indicates the start ratio to set. The default value is 1. + * @since 1.0 + * @version 1.0 + */ + void SetScaleStart(float start) + { + scaleCur_ = static_cast(FloatToInt64(start)); + } + + /** + * @brief Sets the end ratio for scaling this image. + * + * @param end Indicates the end ratio to set. The default value is 1. + * @since 1.0 + * @version 1.0 + */ + void SetScaleEnd(float end) + { + scaleEnd_ = static_cast(FloatToInt64(end)); + } + + /** + * @brief Sets the duration for this animator, in milliseconds. + * + * The durations of image scaling and rotation are the same and cannot be set separately. + * + * @param durationTime Indicates the duration to set. + * @since 1.0 + * @version 1.0 + */ + void SetDurationTime(uint16_t durationTime) + { + animator_.SetTime(durationTime + delayTime_); + } + + /** + * @brief Sets the delay time for this animator, in milliseconds. + * + * The delays of image scaling and rotation are the same and cannot be set separately. + * + * @param delayTime Indicates the delay time to set. + * @since 1.0 + * @version 1.0 + */ + void SetDelayTime(uint16_t delayTime) + { + animator_.SetTime(animator_.GetTime() - delayTime_ + delayTime); + delayTime_ = delayTime; + } + + /** + * @brief Sets the easing function for this animator. + * + * The easing functions for image scaling and rotation are the same and cannot be set separately. + * + * @param easingFunc Indicates the easing function to set. The animation moves at a constant velocity by default. + * For details, see {@link EasingEquation}. + * @since 1.0 + * @version 1.0 + */ + void SetEasingFunc(EasingFunc easingFunc) + { + easingFunc_ = easingFunc; + } + + /** + * @brief Cancels this animator. + * + * After being cancelled, the animator will stop in the current playback state. + * + * @since 1.0 + * @version 1.0 + */ + void Cancel(); + + /** + * @brief Displays the original image. + * + * The configured parameters are reserved and will not be reset. + * + * @since 1.0 + * @version 1.0 + */ + void Reset(); + + /** + * @brief Sets the coordinates of the rotation and scaling pivots for this image. + * + * The coordinates represent the position relative to this image. For example, setting the x-coordinate and + * y-coordinate of the rotation or scaling center to the half of the image width and height respectively + * means the rotation or scaling is going to be performed around the center of this image. + * + * @param x Indicates the x-coordinate to set. + * @param y Indicates the y-coordinate to set. + * @since 1.0 + * @version 1.0 + */ + void SetPivot(float x, float y) + { + pivot_.x_ = x; + pivot_.y_ = y; + } + + /** + * @brief Represents a listener that contains a callback to be invoked when this animator stops. + * + * @since 1.0 + * @version 1.0 + */ + class AnimatorStopListener : public HeapBase { + public: + /** + * @brief A destructor used to delete an AnimatorStopListener instance. + * + * @since 1.0 + * @version 1.0 + */ + virtual ~AnimatorStopListener() {} + + /** + * @brief Called when this animator stops. This is a pure virtual function, which needs + * your inheritance and implementation. + * + * @param view Indicates the instance of this view. + * @since 1.0 + * @version 1.0 + */ + virtual void OnAnimatorStop(UIView& view) = 0; + }; + + /** + * @brief Sets the listener for the stop of this animator. + * + * @param listener Indicates the listener to set. For details, see {@link AnimatorStopListener}. + * @since 1.0 + * @version 1.0 + */ + void SetAnimatorStopListener(AnimatorStopListener* listener) + { + listener_ = listener; + } + +private: + class TextureMapperAnimatorCallback : public AnimatorCallback { + public: + virtual ~TextureMapperAnimatorCallback() {} + + void Callback(UIView* view) override; + + void OnStop(UIView& view) override; + }; + + static constexpr int16_t SCALE_CONVERTION = 256; + + void Callback(); + + TextureMapperAnimatorCallback animatorCallback_; + Animator animator_; + AnimatorStopListener* listener_; + + Vector2 pivot_; + int16_t rotateCur_; + int16_t rotateStart_; + int16_t rotateEnd_; + int16_t scaleCur_; + int16_t scaleStart_; + int16_t scaleEnd_; + uint16_t delayTime_; + EasingFunc easingFunc_; +}; +} // namespace OHOS +#endif // GRAPHIC_LITE_UI_TEXTURE_MAPPER_H diff --git a/interfaces/kits/components/ui_time_picker.h b/interfaces/kits/components/ui_time_picker.h new file mode 100755 index 0000000..91cf392 --- /dev/null +++ b/interfaces/kits/components/ui_time_picker.h @@ -0,0 +1,334 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +/** + * @addtogroup UI_Components + * @{ + * + * @brief Defines UI components such as buttons, texts, images, lists, and progress bars. + * + * @since 1.0 + * @version 1.0 + */ + +/** + * @file ui_time_picker.h + * + * @brief Defines the attributes and functions of the UITimePicker class. + * + * @since 1.0 + * @version 1.0 + */ + +#ifndef GRAPHIC_LITE_UI_TIME_PICKER_H +#define GRAPHIC_LITE_UI_TIME_PICKER_H + +#include "components/ui_picker.h" + +namespace OHOS { +/** + * @brief Defines the time picker. The time is in the format of "hour:minute" or "hour:minute:second". + * The selected time is highlighted. + * + * @since 1.0 + * @version 1.0 + */ +class UITimePicker : public UIViewGroup { +public: +#if ENABLE_ROTATE_INPUT + static constexpr const char* HOUR_LIST_NAME = "hour"; + static constexpr const char* MIN_LIST_NAME = "minute"; + static constexpr const char* SEC_LIST_NAME = "second"; +#endif + /** + * @brief A constructor used to create a UITimePicker instance. + * + * @since 1.0 + * @version 1.0 + */ + UITimePicker(); + + /** + * @brief A destructor used to delete the UITimePicker instance. + * + * @since 1.0 + * @version 1.0 + */ + virtual ~UITimePicker(); + + /** + * @brief Obtains the view type. + * + * @return Returns the view type. For details, see {@link UIViewType}. + * @since 1.0 + * @version 1.0 + */ + UIViewType GetViewType() const override + { + return UI_TIME_PICKER; + } + + /** + * @brief Sets the time currently selected in the time picker. + * + * @param value Indicates the pointer to the selected time, which is in the format of "hour:minute:second", + * for example, 10:12:50. The second is optional and depends on the setting of {@link EnableSecond}. + * The time must be a valid value. For example, the hour value must range from 0 to 23. + * @return Returns true if the setting is successful; returns false otherwise. + * @since 1.0 + * @version 1.0 + */ + bool SetSelected(const char* value); + + /** + * @brief Obtains the time currently selected in the time picker. + * + * @return Returns a string representing the selected time. The time is in the format of "hour:minute:second", + * for example, 10:12:50. The second is optional and depends on the setting of {@link EnableSecond}. + * @since 1.0 + * @version 1.0 + */ + const char* GetSelectValue() + { + return selectedValue_; + } + + /** + * @brief Obtains the hour currently selected in the time picker. + * + * @return Returns a string representing the selected hour, for example, 10. + * @since 1.0 + * @version 1.0 + */ + const char* GetSelectHour() const + { + return selectedHour_; + } + + /** + * @brief Obtains the minute currently selected in the time picker. + * + * @return Returns a string representing the selected minute, for example, 12. + * @since 1.0 + * @version 1.0 + */ + const char* GetSelectMinute() const + { + return selectedMinute_; + } + + /** + * @brief Obtains the second currently selected in the time picker. + * + * @return Returns a string representing the selected second, for example, 50. + * @since 1.0 + * @version 1.0 + */ + const char* GetSelectSecond() const + { + return selectedSecond_; + } + + /** + * @brief Sets the height of each item in the time picker. + * + * @param height Indicates the height of each item. + * @since 1.0 + * @version 1.0 + */ + void SetItemHeight(int16_t height); + + /** + * @brief Sets whether to enable seconds in the time picker. + * + * @param state Specifies whether to enable seconds in the time picker. Value true means to enable seconds, + * and value false means to disable seconds. The default value is false. + * @since 1.0 + * @version 1.0 + */ + void EnableSecond(bool state); + + /** + * @brief Sets the text format in the time picker, including the font ID and color. + * + * @param backgroundFontId Indicates the font ID of the background text. + * @param highlightFontId Indicates the font ID of the highlighted text. + * @param backgroundColor Indicates the color of the background text. + * @param highlightColor Indicates the color of the highlighted text. + * @since 1.0 + * @version 1.0 + */ + void SetTextStyle(uint8_t backgroundFontId, + uint8_t highlightFontId, + ColorType backgroundColor, + ColorType highlightColor); + + /** + * @brief Sets the text color in the time picker. + * + * @param backgroundColor Indicates the color of the background text. + * @param highlightColor Indicates the color of the highlighted text. + * @since 1.0 + * @version 1.0 + */ + void SetTextColor(ColorType backgroundColor, ColorType highlightColor); + + /** + * @brief Sets the font name and size for the background text. + * + * @param name Indicates the pointer to the font name to set. + * @param size Indicates the font size to set. + * @since 1.0 + * @version 1.0 + */ + void SetBackgroundFont(const char* name, uint8_t size); + + /** + * @brief Sets the font name and size for the highlighted text. + * + * @param name Indicates the pointer to the font name to set. + * @param size Indicates the font size to set. + * @since 1.0 + * @version 1.0 + */ + void SetHighlightFont(const char* name, uint8_t size); + + /** + * @brief Sets the width for the time picker. + * + * @param width Indicates the width to set. + * @since 1.0 + * @version 1.0 + */ + void SetWidth(int16_t width) override; + + /** + * @brief Sets the height for the time picker. + * + * @param height Indicates the height to set. + * @since 1.0 + * @version 1.0 + */ + void SetHeight(int16_t height) override; + + /** + * @brief Defines the listener used by the time picker. This listener is triggered when an item is selected + * after sliding stops. + * + * @since 1.0 + * @version 1.0 + */ + class SelectedListener : public HeapBase { + public: + /** + * @brief A constructor used to create a SelectedListener instance. + * + * @since 1.0 + * @version 1.0 + */ + SelectedListener() {} + + /** + * @brief A destructor used to delete the SelectedListener instance. + * + * @since 1.0 + * @version 1.0 + */ + ~SelectedListener() {} + + /** + * @brief Called when an item is selected after sliding stops. This function is implemented by applications. + * + * @param picker Indicates the time picker instance. + * @since 1.0 + * @version 1.0 + */ + virtual void OnTimePickerStoped(UITimePicker& picker) {} + }; + + /** + * @brief Registers a listener for a selected event. + * + * @param timePickerListener Indicates the listener to register. For details, see {@link SelectedListener}. + * + * @since 1.0 + * @version 1.0 + */ + void RegisterSelectedListener(SelectedListener* timePickerListener) + { + timePickerListener_ = timePickerListener; + } + +private: + class UIPickerListener : public UIPicker::SelectedListener { + public: + UIPickerListener(UITimePicker* timePicker) + { + timePicker_ = timePicker; + } + + ~UIPickerListener() {} + + virtual void OnPickerStoped(UIPicker& picker) override + { + if (timePicker_ != nullptr) { + timePicker_->TimeSelectedCallback(); + } + } + + private: + UITimePicker* timePicker_; + }; + static constexpr uint8_t TIME_START = 0; + static constexpr uint8_t HOUR_END = 23; + static constexpr uint8_t MIN_END = 59; + static constexpr uint8_t SEC_END = 59; + static constexpr uint8_t BUF_SIZE = 3; + static constexpr uint8_t SELECTED_VALUE_SIZE = 9; + static constexpr uint8_t SEC_VISIBLE_COUNT = 3; + static constexpr uint8_t SEC_INVISIBLE_COUNT = 2; + void TimeSelectedCallback(); + void InitTimePicker(); + void DeInitTimePicker(); + void RefreshTimePicker(); + bool RefreshSelected(const char* value); + void InitPicker(UIPicker*& picker, int16_t start, int16_t end); + void DeInitPicker(UIPicker*& picker); + void GetValueByIndex(char* value, uint8_t len, uint16_t index, int16_t start, int16_t end); + UIPicker* hourPicker_; + UIPicker* minutePicker_; + UIPicker* secondPicker_; + char selectedValue_[SELECTED_VALUE_SIZE]; + char selectedHour_[BUF_SIZE]; + char selectedMinute_[BUF_SIZE]; + char selectedSecond_[BUF_SIZE]; + bool secVisible_; + const char* setSelectedTime_; + uint16_t pickerWidth_; + uint16_t itemsHeight_; + int16_t xPos_; + uint8_t highlightFontId_; + uint8_t backgroundFontId_; + uint8_t backgroundFontSize_; + uint8_t highlightFontSize_; + char* backgroundFontName_; + char* highlightFontName_; + ColorType highlightColor_; + ColorType backgroundColor_; + UIPickerListener pickerListener_; + SelectedListener* timePickerListener_; +}; +} // namespace OHOS +#endif // GRAPHIC_LITE_UI_TIME_PICKER_H diff --git a/interfaces/kits/components/ui_toggle_button.h b/interfaces/kits/components/ui_toggle_button.h new file mode 100755 index 0000000..7732da4 --- /dev/null +++ b/interfaces/kits/components/ui_toggle_button.h @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +/** + * @addtogroup UI_Components + * @{ + * + * @brief Defines UI components such as buttons, texts, images, lists, and progress bars. + * + * @since 1.0 + * @version 1.0 + */ + +/** + * @file ui_toggle_button.h + * + * @brief Defines the attributes and common functions of a toggle button. + * + * Each toggle button contains two images, one for pressing and the other for releasing. + * + * @since 1.0 + * @version 1.0 + */ + +#ifndef GRAPHIC_LITE_UI_TOGGLE_BUTTON_H +#define GRAPHIC_LITE_UI_TOGGLE_BUTTON_H + +#include "components/ui_checkbox.h" +#include "components/ui_image_view.h" + +namespace OHOS { +/** + * @brief Represents a toggle button. + * + * Each toggle button contains two images, one for pressing and the other for releasing. + * + * @see UICheckBox + * @since 1.0 + * @version 1.0 + */ +class UIToggleButton : public UICheckBox { +public: + /** + * @brief A constructor used to create a UIToggleButton instance. + * + * @since 1.0 + * @version 1.0 + */ + UIToggleButton(); + + /** + * @brief A destructor used to delete the UIToggleButton instance. + * + * @since 1.0 + * @version 1.0 + */ + virtual ~UIToggleButton() {} + + /** + * @brief Obtains the component type. + * + * @return Returns the component type, as defined in {@link UIViewType}. + * @since 1.0 + * @version 1.0 + */ + UIViewType GetViewType() const override + { + return UI_TOGGLE_BUTTON; + } + + void OnDraw(const Rect& invalidatedArea) override; + + /** + * @brief Sets the state for this toggle button. + * + * @param state Indicates the state of this toggle button. The value true indicates the image displayed for + * On, and false indicates the image displayed for Off. If this function is not called, the + * image is displayed for Off. + * @since 1.0 + * @version 1.0 + */ + void SetState(bool state); + + /** + * @brief Obtains the state of this toggle button. + * + * @return Returns true if the image for On is displayed; returns false if the image is + * displayed for Off. + * @since 1.0 + * @version 1.0 */ + bool GetState() const + { + return (state_ != UNSELECTED); + } + +private: + static constexpr int16_t DEFAULT_HOT_WIDTH = 46; + static constexpr int16_t DEFAULT_HOT_HEIGHT = 46; + static constexpr int16_t DEFAULT_WIDTH = 32; + static constexpr int16_t DEFAULT_CORNER_RADIUS = 11; + static constexpr int16_t DEAFULT_RADIUS_DIFF = 2; + static constexpr uint8_t DEFAULT_UNSELECTED_OPA = 97; + static constexpr uint8_t DEFAULT_BG_RED = 31; + static constexpr uint8_t DEFAULT_BG_GREEN = 113; + static constexpr uint8_t DEFAULT_BG_BLUE = 255; + + int16_t width_; + int16_t height_; + uint16_t corner_; + uint16_t radius_; + int16_t rectWidth_; + + void CalculateSize(); +}; // class UIToggleButton +} // namespace OHOS +#endif // GRAPHIC_LITE_UI_TOGGLE_BUTTON_H diff --git a/interfaces/kits/components/ui_video.h b/interfaces/kits/components/ui_video.h new file mode 100755 index 0000000..c04ff29 --- /dev/null +++ b/interfaces/kits/components/ui_video.h @@ -0,0 +1,498 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +/** + * @addtogroup UI_Components + * @{ + * + * @brief Defines UI components such as buttons, texts, images, lists, and progress bars. + * + * @since 5.0 + * @version 3.0 + */ + +/** + * @file ui_video.h + * + * @brief Declares the functions related to video playbacks. + * + * @since 5.0 + * @version 3.0 + */ + +#ifndef GRAPHIC_LITE_UI_VIDEO_H +#define GRAPHIC_LITE_UI_VIDEO_H + +#include "animator/animator.h" +#include "components/ui_label.h" +#include "components/ui_slider.h" +#include "components/ui_surface_view.h" +#include "components/ui_toggle_button.h" +#include "components/ui_view_group.h" +#include "player.h" + +#ifndef VERSION_LITE +namespace OHOS { +using namespace OHOS::Media; +/** + * @brief Provides the functions related to video playbacks. + * + * @since 5.0 + * @version 3.0 + */ +class UIVideo : public UIViewGroup, + public UIView::OnClickListener, + public UIView::OnTouchListener, + public UISlider::UISliderEventListener { +public: + /** + * @brief A constructor used to create a UIVideo instance for playback. + * + * @since 5.0 + * @version 3.0 + */ + UIVideo(); + + /** + * @brief A destructor used to delete the UIVideo instance for playback. + * + * @since 5.0 + * @version 3.0 + */ + virtual ~UIVideo(); + + /** + * @brief Sets the source file to be played. + * + * @param source Indicates the pointer to the source file path. + * @return Returns true if the setting is successful; returns false otherwise. + * @since 5.0 + * @version 3.0 + */ + bool SetSrc(const char* source); + + /** + * @brief Obtains the path of the source file to be played. + * + * @return Returns the path of the source file to be played. + * @since 5.0 + * @version 3.0 + */ + const char* GetSrc() + { + return src_; + } + + /** + * @brief Prepares for the playback. You must call this function after {@link SetSource}. + * + * @return Returns true if the preparation is successful; returns false otherwise. + * @since 5.0 + * @version 3.0 + */ + bool Prepare(); + + /** + * @brief Plays this video. + * + * @return Returns true if this video is played; returns false otherwise. + * @since 5.0 + * @version 3.0 + */ + bool Play(); + + /** + * @brief Checks whether this video is playing. + * + * @return Returns true if this video is playing; returns false otherwise. + * @since 5.0 + * @version 3.0 + */ + bool IsPlaying(); + + /** + * @brief Pauses the video being played. + * + * @return Returns true if the video is paused; returns false otherwise. + * @since 5.0 + * @version 3.0 + */ + bool Pause(); + + /** + * @brief Stops playing this video. + * + * @return Returns true if this video is stopped; returns false otherwise. + * @since 5.0 + * @version 3.0 + */ + bool Stop(); + + /** + * @brief Changes the playback position. + * + * @param mSeconds Indicates the target playback position, in milliseconds. + * @return Returns true if the playback position is changed; returns false otherwise. + * @since 5.0 + * @version 3.0 + */ + bool Rewind(int64_t mSeconds); + + /** + * @brief Sets the playback volume. + * + * @param Indicates the volume of the left audio channel to set, ranging from 0 to 100. + * @param rightVolume Indicates the volume of the right audio channel to set, ranging from 0 to 1. + * @return Returns true if the setting is successful; returns false otherwise. + * @since 5.0 + * @version 3.0 + */ + bool SetVolume(float leftVolume, float rightVolume); + + /** + * @brief Sets whether to loop playback. + * + * @param loop Specifies whether to loop playback. The value true means that the playback loops, + * and false means the opposite case. + * @return Returns true if the setting is successful; returns false otherwise. + * @since 5.0 + * @version 3.0 + */ + bool EnableSingleLooping(bool loop); + + /** + * @brief Checks whether the playback loops. + * + * @return Returns true if the playback loops; returns false otherwise. + * @since 5.0 + * @version 3.0 + */ + bool IsSingleLooping(); + + /** + * @brief Obtains the current playback time. + * + * @param time Indicates the current playback time, in milliseconds. + * @return Returns true if the operation is successful; returns false otherwise. + * @since 5.0 + * @version 3.0 + */ + bool GetCurrentTime(int64_t& time); + + /** + * @brief Obtains the total video duration. + * + * @param duration Indicates the total duration, in milliseconds. + * @return Returns true if the duration is obtained; returns false otherwise. + * @since 5.0 + * @version 3.0 + */ + bool GetDuration(int64_t& duration); + + /** + * @brief Resets the player to the initial state. + * + * @return Returns true if the player is reset; returns false otherwise. + * @since 5.0 + * @version 3.0 + */ + bool Reset(); + + /** + * @brief Sets whether to show the playback controller. + * + * @param show Specifies whether to show the playback controller. The value true means showing + * the playback controller, and false means the opposite case. + * @since 5.0 + * @version 3.0 + */ + void ShowController(bool show); + + /** + * @brief Provides callbacks for events that occur during video playback. + * + * @since 5.0 + * @version 3.0 + */ + class VideoPlayerListener { + public: + /** + * @brief A constructor used to create a VideoPlayerListener instance. + * + * @since 5.0 + * @version 3.0 + */ + VideoPlayerListener() {} + + /** + * @brief A destructor used to delete the VideoPlayerListener instance. + * + * @since 5.0 + * @version 3.0 + */ + virtual ~VideoPlayerListener() {}; + + /** + * @brief Called when the playback is complete. + * + * @since 5.0 + * @version 3.0 + */ + virtual void OnPlaybackComplete() {} + + /** + * @brief Called when a video playback error occurs. + * + * @param errorType Indicates the error type. + * @param eerrorCode Indicates the error code. + * @since 5.0 + * @version 3.0 + */ + virtual void OnError(int32_t errorType, int32_t errorCode) {} + + /** + * @brief Called when playback information is received. + * + * @param type Indicates the information type. + * @param extra Indicates the information code. + * @since 5.0 + * @version 3.0 + */ + virtual void OnInfo(int32_t type, int32_t extra) {} + + /** + * @brief Called when the video image size changes. + * + * @param width Indicates the video width. + * @param height Indicates the video height. + * @since 5.0 + * @version 3.0 + */ + virtual void OnVideoSizeChanged(int32_t width, int32_t height) {} + + /** + * @brief Called when this video is rewound. + * + * @since 5.0 + * @version 3.0 + */ + virtual void OnRewindToComplete() {} + + /** + * @brief Called when this video is paused. + * + * @since 5.0 + * @version 3.0 + */ + virtual void OnPlaybackPause() {} + + /** + * @brief Called when this video is played. + * + * @since 5.0 + * @version 3.0 + */ + virtual void OnPlaybackPlay() {} + + /** + * @brief Called when this video is stopped. + * + * @since 5.0 + * @version 3.0 + */ + virtual void OnPlaybackStop() {} + }; + + /** + * @brief Sets a listener for monitoring video playbacks. + * + * @param listener Indicates the pointer to the listener to set. + * @since 5.0 + * @version 3.0 + */ + void SetVideoPlayerListener(VideoPlayerListener* listener); + +private: + class SliderAnimatorCallback : public AnimatorCallback { + public: + SliderAnimatorCallback(UIVideo* video, UISlider* slider, UILabel* label) + { + video_ = video; + slider_ = slider; + timeLabel_ = label; + } + + virtual ~SliderAnimatorCallback() {} + void Callback(UIView* view) override; + void SetPlayButton(UIToggleButton* toggleButton) + { + playButton_ = toggleButton; + } + + void SetSliderAnimator(Animator* animator) + { + sliderAnimator_ = animator; + } + + void SetDuration(int64_t duration) + { + duration_ = duration; + } + + void ResetTickTime() + { + if (sliderAnimator_ != nullptr) { + tickCount_ = sliderAnimator_->GetRunTime(); + } + } + + friend class UIVideo; + private: + uint32_t tickCount_ = 0; + int64_t duration_ = 0; + UIVideo* video_ = nullptr; + UISlider* slider_ = nullptr; + UILabel* timeLabel_ = nullptr; + UIToggleButton* playButton_ = nullptr; + Animator* sliderAnimator_ = nullptr; + }; + + void InitVideo(); + void InitControllerLabel(); + void InitControllerButton(); + void InitControllerSlider(); + void DeleteController(); + void SetSurfaceInfo(); + void OnVideoComplete(); + bool GetTimerFromMSecond(int64_t currentTime, char* timer, int32_t len); + + bool OnClick(UIView& view, const ClickEvent& event) override; + bool OnPress(UIView& view, const PressEvent& event) override; + void OnChange(int32_t progress) override; + + class PlayerListener : public Media::PlayerCallback { + public: + PlayerListener() {} + virtual ~PlayerListener() {} + void OnPlaybackComplete() override + { + if (video_ != nullptr) { + video_->OnVideoComplete(); + } + if (videoPlayerListener_ != nullptr) { + videoPlayerListener_->OnPlaybackComplete(); + } + } + + void OnError(int32_t errorType, int32_t errorCode) override + { + if (videoPlayerListener_ != nullptr) { + videoPlayerListener_->OnError(errorType, errorCode); + } + } + + void OnInfo(int32_t type, int32_t extra) override + { + if (videoPlayerListener_ != nullptr) { + videoPlayerListener_->OnInfo(type, extra); + } + } + + void OnVideoSizeChanged(int32_t width, int32_t height) override + { + if (videoPlayerListener_ != nullptr) { + videoPlayerListener_->OnVideoSizeChanged(width, height); + } + } + + void OnRewindToComplete() override + { + if (videoPlayerListener_ != nullptr) { + videoPlayerListener_->OnRewindToComplete(); + } + } + + void OnPlaybackPause() + { + if (videoPlayerListener_ != nullptr) { + videoPlayerListener_->OnPlaybackPause(); + } + } + + void OnPlaybackPlay() + { + if (videoPlayerListener_ != nullptr) { + videoPlayerListener_->OnPlaybackPlay(); + } + } + + void OnPlaybackStop() + { + if (videoPlayerListener_ != nullptr) { + videoPlayerListener_->OnPlaybackStop(); + } + } + + void SetVideoPlayer(UIVideo* video) + { + video_ = video; + } + + void SetVideoPlayerListerner(VideoPlayerListener* listener) + { + videoPlayerListener_ = listener; + } + + private: + UIVideo* video_ = nullptr; + VideoPlayerListener* videoPlayerListener_ = nullptr; + }; + + bool completeFlag_ = false; + float leftVolumeValue_ = DEFAULT_VOLUME; + float rightVolumeValue_ = DEFAULT_VOLUME; + int64_t duration_ = 0; + const char* src_ = nullptr; + std::shared_ptr videoPlayer_ = nullptr; + UIViewGroup* controllerGroup_ = nullptr; + UILabel* totalTimeLabel_ = nullptr; + UILabel* currentTimeLabel_ = nullptr; + UILabel* titleLabel_ = nullptr; + UISlider* playSlider_ = nullptr; + Animator* sliderAnimator_ = nullptr; + SliderAnimatorCallback* sliderAnimatorCallback_ = nullptr; + UIToggleButton* volumeButton_ = nullptr; + UISurfaceView* surfaceView_ = nullptr; + UIToggleButton* playButton_ = nullptr; + UIToggleButton* pauseButton_ = nullptr; + VideoPlayerListener* videoPlayerListener_ = nullptr; + std::shared_ptr playerListener_ = nullptr; + + static constexpr uint16_t DEFAULT_VIEW_WIDTH = 960; + static constexpr uint16_t DEFAULT_VIEW_HEIGHT = 480; + static constexpr uint16_t TOGGLE_BUTTON_WIDTH = 32; + static constexpr uint16_t TOGGLE_BUTTON_HEIGHT = 32; + static constexpr uint16_t TIME_LABEL_WIDTH = 300; + static constexpr uint16_t TIME_LABEL_HEIGHT = 20; + static constexpr uint16_t KNOB_WIDTH = 18; + static constexpr uint16_t FONT_DEFAULT_SIZE = 14; + static constexpr uint16_t MAX_VOLUME = 300; + static constexpr uint16_t HIDE_MILLI_SECOND = 5000; + static constexpr float DEFAULT_VOLUME = 0.5; +}; +} // namespace OHOS + +#endif // VERSION_LITE +#endif // GRAPHIC_LITE_UI_VIDEO_H \ No newline at end of file diff --git a/interfaces/kits/components/ui_view.h b/interfaces/kits/components/ui_view.h new file mode 100755 index 0000000..c432f59 --- /dev/null +++ b/interfaces/kits/components/ui_view.h @@ -0,0 +1,1516 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +/** + * @addtogroup UI_Components + * @{ + * + * @brief Defines UI components such as buttons, texts, images, lists, and progress bars. + * + * @since 1.0 + * @version 1.0 + */ + +/** + * @file ui_view.h + * + * @brief Declares the base class of a view, providing basic view attributes and operations. All views are derived + * from this class. + * + * @since 1.0 + * @version 1.0 + */ + +#ifndef GRAPHIC_LITE_UI_VIEW_H +#define GRAPHIC_LITE_UI_VIEW_H + +#include "color.h" +#include "events/cancel_event.h" +#include "events/click_event.h" +#include "events/drag_event.h" +#include "events/event.h" +#include "events/long_press_event.h" +#include "events/press_event.h" +#include "events/release_event.h" +#if ENABLE_ROTATE_INPUT +#include "events/rotate_event.h" +#endif +#include "geometry2d.h" +#include "graphic_log.h" +#include "heap_base.h" +#include "style.h" +#include "transform.h" + +namespace OHOS { +/* Enumerates view types. */ +enum UIViewType : uint8_t { + UI_ROOT_VIEW = 0, + UI_VIEW_GROUP, + UI_LABEL, + UI_ARC_LABEL, + UI_LABEL_BUTTON, + UI_CHECK_BOX, + UI_TOGGLE_BUTTON, + UI_RADIO_BUTTON, + UI_IMAGE_VIEW, + UI_BOX_PROGRESS, + UI_SLIDER, + UI_CIRCLE_PROGRESS, + UI_SCROLL_VIEW, + UI_LIST, + UI_DIGITAL_CLOCK, + UI_ANALOG_CLOCK, + UI_PICKER, + UI_SWIPE_VIEW, + UI_TIME_PICKER, + UI_ABSTRACT_CLOCK, + UI_ABSTRACT_PROGRESS, + UI_ABSTRACT_SCROLL, + UI_AXIS, + UI_BUTTON, + UI_CANVAS, + UI_CHART, + UI_IMAGE_ANIMATOR_VIEW, + UI_REPEAT_BUTTON, + UI_TEXTURE_MAPPER, + UI_DIALOG, + UI_QRCODE, + UI_NUMBER_MAX +}; + +#if ENABLE_DEBUG +const char* const VIEW_TYPE_STRING[UI_NUMBER_MAX] = { + "RootView", "UIViewGroup", "UILabel", + "UIArcLabel", "UILabelButton", "UICheckBox", + "UIToggleButton", "UIRadioButton", "UIImageView", + "UIBoxProgress", "UISlider", "UICircleProgress", + "UIScrollView", "UIList", "UIDigitalClock", + "UIAnalogClock", "UIPicker", "UISwipeView", + "UITimePicker", "UIAbstractClock", "UIAbstractProgress", + "UIAbstractScroll", "UIAxis", "UIButton", + "UICanvas", "UIChart", "UIImageAnimatorView", + "UIRepeatButton", "UITextureMapper", "UIDialog", + "UIQrcode", +}; +#endif // ENABLE_DEBUG + +/** + * @brief Defines the base class of a view, providing basic view attributes and operations. All views are derived + * from this class. + * + * @since 1.0 + * @version 1.0 + */ +class UIView : public HeapBase { +public: + /** + * @brief Defines a click event listener. You need to register this listener with the view to listen to + * click events. + * + * @since 1.0 + * @version 1.0 + */ + class OnClickListener : public HeapBase { + public: + /** + * @brief Called when a view is clicked. + * @param view Indicates the view clicked. + * @param event Indicates the click event. + * @return Returns true if the event is consumed; returns false otherwise. + * (If an event is consumed, it is not transferred to the parent view. If an event is not consumed, + * it is transferred to the parent view after local processing is complete.) + * @since 1.0 + * @version 1.0 + */ + virtual bool OnClick(UIView& view, const ClickEvent& event) + { + return false; + } + + /** + * @brief A destructor used to delete the OnClickListener instance. + * @since 1.0 + * @version 1.0 + */ + virtual ~OnClickListener() {} + }; + + /** + * @brief Defines a long-press event listener. You need to register this listener with the view to listen to + * long-press events. + * + * @since 1.0 + * @version 1.0 + */ + class OnLongPressListener : public HeapBase { + public: + /** + * @brief Called when a view is long pressed. + * @param view Indicates the view long pressed. + * @param event Indicates the long-press event. + * @return Returns true if the event is consumed; returns false otherwise. + * (If an event is consumed, it is not transferred to the parent view. If an event is not consumed, + * it is transferred to the parent view after local processing is complete.) + * @since 1.0 + * @version 1.0 + */ + virtual bool OnLongPress(UIView& view, const LongPressEvent& event) + { + return false; + } + + /** + * @brief A destructor used to delete the OnLongPressListener instance. + * @since 1.0 + * @version 1.0 + */ + virtual ~OnLongPressListener() {} + }; + + /** + * @brief Defines a drag event listener. You need to register this listener with the view to listen to drag events. + * + * @since 1.0 + * @version 1.0 + */ + class OnDragListener : public HeapBase { + public: + /** + * @brief Called when a view starts to drag. + * @param view Indicates the view dragged. + * @param event Indicates the drag event. + * @return Returns true if the event is consumed; returns false otherwise. + * (If an event is consumed, it is not transferred to the parent view. If an event is not consumed, + * it is transferred to the parent view after local processing is complete.) + * @since 1.0 + * @version 1.0 + */ + virtual bool OnDragStart(UIView& view, const DragEvent& event) + { + return false; + } + + /** + * @brief Called when a view is being dragged. + * @param view Indicates the view dragged. + * @param event Indicates the drag event. + * @return Returns true if the event is consumed; returns false otherwise. + * (If an event is consumed, it is not transferred to the parent view. If an event is not consumed, + * it is transferred to the parent view after local processing is complete.) + * @since 1.0 + * @version 1.0 + */ + virtual bool OnDrag(UIView& view, const DragEvent& event) + { + return false; + } + + /** + * @brief Called when a view stops dragging. + * @param view Indicates the view dragged. + * @param event Indicates the drag event. + * @return Returns true if the event is consumed; returns false otherwise. + * (If an event is consumed, it is not transferred to the parent view. If an event is not consumed, + * it is transferred to the parent view after local processing is complete.) + * @since 1.0 + * @version 1.0 + */ + virtual bool OnDragEnd(UIView& view, const DragEvent& event) + { + return false; + } + + /** + * @brief A destructor used to delete the OnDragListener instance. + * @since 1.0 + * @version 1.0 + */ + virtual ~OnDragListener() {} + }; + + /** + * @brief Defines a touch event listener. You need to register this listener with the view to listen to touch + * events. + * + * @since 1.0 + * @version 1.0 + */ + class OnTouchListener : public HeapBase { + public: + /** + * @brief Called when a view is pressed. + * @param view Indicates the view pressed. + * @param event Indicates the press event. + * @return Returns true if the event is consumed; returns false otherwise. + * (If an event is consumed, it is not transferred to the parent view. If an event is not consumed, + * it is transferred to the parent view after local processing is complete.) + * @since 1.0 + * @version 1.0 + */ + virtual bool OnPress(UIView& view, const PressEvent& event) + { + return false; + } + + /** + * @brief Called when a view is released. + * @param view Indicates the view released. + * @param event Indicates the release event. + * @return Returns true if the event is consumed; returns false otherwise. + * (If an event is consumed, it is not transferred to the parent view. If an event is not consumed, + * it is transferred to the parent view after local processing is complete.) + * @since 1.0 + * @version 1.0 + */ + virtual bool OnRelease(UIView& view, const ReleaseEvent& event) + { + return false; + } + + /** + * @brief Called when a click event on a view is canceled. + * @param view Indicates the view on which a click event is canceled. + * @param event Indicates the cancel event. + * @return Returns true if the event is consumed; returns false otherwise. + * (If an event is consumed, it is not transferred to the parent view. If an event is not consumed, + * it is transferred to the parent view after local processing is complete.) + * @since 1.0 + * @version 1.0 + */ + virtual bool OnCancel(UIView& view, const CancelEvent& event) + { + return false; + } + + /** + * @brief A destructor used to delete the OnTouchListener instance. + * @since 1.0 + * @version 1.0 + */ + virtual ~OnTouchListener() {} + }; + +#if ENABLE_ROTATE_INPUT + /** + * @brief 声明旋转事件监听类。你需要注册此监听类以响应旋转事件。 + * @since 5.0 + * @version 3.0 + */ + class OnRotateListener : public HeapBase { + public: + /** + * @brief 当组件收到旋转事件时调用 + * @param view 响应旋转的组件 + * @param event 旋转事件 + * @return 如果事件被消费返回true, 否则返回false. + * @since 5.0 + * @version 3.0 + */ + virtual bool OnRotate(UIView& view, const RotateEvent& event) + { + return true; + } + /** + * @brief 析构函数,删除OnRotateListener旋转事件监听类实例. + * @since 5.0 + * @version 3.0 + */ + virtual ~OnRotateListener() {} + }; + + /** + * @brief 当旋转事件传入组件时调用以产生对应响应 + * @param event 旋转事件 + * @since 5.0 + * @version 3.0 + */ + virtual bool OnRotateEvent(const RotateEvent& event); + + /** + * @brief 设置当前view组件的旋转事件监听对象 + * @param onRotateListener 输入当前view组件的旋转事件监听对象指针 + * @since 5.0 + * @version 3.0 + */ + void SetOnRotateListener(OnRotateListener* onRotateListener) + { + onRotateListener_ = onRotateListener; + } + + /** + * @brief 获得当前view组件的旋转事件监听对象指针 + * @return 返回当前view组件的旋转事件监听对象指针 + * @since 5.0 + * @version 3.0 + */ + OnRotateListener*& GetOnRotateListener() + { + return onRotateListener_; + } +#endif + + /** + * @brief Stores extra information about a UIView instance. + * @param elementPtr Indicates the void pointer to the extra information about the UIView instance. + * @since 5.0 + * @version 3.0 + */ + struct ViewExtraMsg { + void* elementPtr; + }; + + /** + * @brief A default constructor used to create an UIView instance. + * @since 1.0 + * @version 1.0 + */ + UIView(); + + /** + * @brief A constructor used to create an UIView instance. + * @param id Indicates the pointer to the view ID. + * @since 1.0 + * @version 1.0 + */ + UIView(const char* id) : UIView() + { + id_ = id; + } + + /** + * @brief A destructor used to delete the UIView instance. + * @since 1.0 + * @version 1.0 + */ + virtual ~UIView(); + + /** + * @brief Called before a view is drawn. This function is used to check whether the invalidated area + * can be fully cover by this view so as to optimize the drawing process. + * @param invalidatedArea Indicates the area to judge and returns the covered area when partly coverd. + * @return Returns true if the invalidated area is fully covered; returns false otherwise. + * @since 1.0 + * @version 1.0 + */ + virtual bool OnPreDraw(Rect& invalidatedArea) const; + + /** + * @brief Called when a view is drawn. + * @param invalidatedArea Indicates the area to draw. + * @since 1.0 + * @version 1.0 + */ + virtual void OnDraw(const Rect& invalidatedArea); + + /** + * @brief Called after a view is drawn. + * @param invalidatedArea Indicates the area in which the view is drawn. + * @since 1.0 + * @version 1.0 + */ + virtual void OnPostDraw(const Rect& invalidatedArea) {} + + /** + * @brief Remeasures the view size. + * @since 1.0 + * @version 1.0 + */ + virtual void ReMeasure() {} + + /** + * @brief Refreshes the invalidated area of the view. + * @since 1.0 + * @version 1.0 + */ + void Invalidate(); + + /** + * @brief Refreshes a view in a specified invalidated area. + * @param invalidatedArea Indicates the area to refresh. + * @since 1.0 + * @version 1.0 + */ + void InvalidateRect(const Rect& invalidatedArea); + + /** + * @brief Called when the view is long pressed. + * @param event Indicates the long-press event. + * @return Returns true if the event is consumed; returns false otherwise. + * (If an event is consumed, it is not transferred to the parent view. If an event is not consumed, + * it is transferred to the parent view after local processing is complete.) + * @since 1.0 + * @version 1.0 + */ + virtual bool OnLongPressEvent(const LongPressEvent& event); + + /** + * @brief Called when the view starts to drag. + * @param event Indicates the drag event. + * @return Returns true if the event is consumed; returns false otherwise. + * (If an event is consumed, it is not transferred to the parent view. If an event is not consumed, + * it is transferred to the parent view after local processing is complete.) + * @since 1.0 + * @version 1.0 + */ + virtual bool OnDragStartEvent(const DragEvent& event); + + /** + * @brief Called when the view is being dragged. + * @param event Indicates the drag event. + * @return Returns true if the event is consumed; returns false otherwise. + * (If an event is consumed, it is not transferred to the parent view. If an event is not consumed, + * it is transferred to the parent view after local processing is complete.) + * @since 1.0 + * @version 1.0 + */ + virtual bool OnDragEvent(const DragEvent& event); + + /** + * @brief Called when the view stops dragging. + * @param event Indicates the drag event. + * @return Returns true if the event is consumed; returns false otherwise. + * (If an event is consumed, it is not transferred to the parent view. If an event is not consumed, + * it is transferred to the parent view after local processing is complete.) + * @since 1.0 + * @version 1.0 + */ + virtual bool OnDragEndEvent(const DragEvent& event); + + /** + * @brief Called when the view is clicked. + * @param event Indicates the click event. + * @return Returns true if the event is consumed; returns false otherwise. + * (If an event is consumed, it is not transferred to the parent view. If an event is not consumed, + * it is transferred to the parent view after local processing is complete.) + * @since 1.0 + * @version 1.0 + */ + virtual bool OnClickEvent(const ClickEvent& event); + + /** + * @brief Called when the view is pressed. + * @param event Indicates the press event. + * @return Returns true if the event is consumed; returns false otherwise. + * (If an event is consumed, it is not transferred to the parent view. If an event is not consumed, + * it is transferred to the parent view after local processing is complete.) + * @since 1.0 + * @version 1.0 + */ + virtual bool OnPressEvent(const PressEvent& event); + + /** + * @brief Called when the view is released. + * @param event Indicates the release event. + * @return Returns true if the event is consumed; returns false otherwise. + * (If an event is consumed, it is not transferred to the parent view. If an event is not consumed, + * it is transferred to the parent view after local processing is complete.) + * @since 1.0 + * @version 1.0 + */ + virtual bool OnReleaseEvent(const ReleaseEvent& event); + + /** + * @brief Called when a click event on the view is canceled. + * @param event Indicates the cancel event. + * @return Returns true if the event is consumed; returns false otherwise. + * (If an event is consumed, it is not transferred to the parent view. If an event is not consumed, + * it is transferred to the parent view after local processing is complete.) + * @since 1.0 + * @version 1.0 + */ + virtual bool OnCancelEvent(const CancelEvent& event); + + /** + * @brief Sets a drag event listener for the view. + * @param onDragListener Indicates the pointer to the drag event listener to set. + * @since 1.0 + * @version 1.0 + */ + void SetOnDragListener(OnDragListener* onDragListener) + { + onDragListener_ = onDragListener; + } + + /** + * @brief Obtains the drag event listener for the view. + * @return Returns the drag event listener. + * @since 1.0 + * @version 1.0 + */ + OnDragListener*& GetOnDragListener() + { + return onDragListener_; + } + + /** + * @brief Sets a click event listener for the view. + * @param onClickListener Indicates the pointer to the click event listener to set. + * @since 1.0 + * @version 1.0 + */ + void SetOnClickListener(OnClickListener* onClickListener) + { + onClickListener_ = onClickListener; + } + + /** + * @brief Obtains the click event listener for the view. + * @return Returns the click event listener. + * @since 1.0 + * @version 1.0 + */ + OnClickListener*& GetOnClickListener() + { + return onClickListener_; + } + + /** + * @brief Sets a long-press event listener for the view. + * @param onLongPressListener Indicates the pointer to the long-press event listener to set. + * @since 1.0 + * @version 1.0 + */ + void SetOnLongPressListener(OnLongPressListener* onLongPressListener) + { + onLongPressListener_ = onLongPressListener; + } + + /** + * @brief Obtains the long-press event listener for the view. + * @return Returns the long-press event listener. + * @since 1.0 + * @version 1.0 + */ + OnLongPressListener*& GetOnLongPressListener() + { + return onLongPressListener_; + } + + /** + * @brief Sets a touch event listener for the view. + * @param onTouchListener Indicates the pointer to the touch event listener to set. + * @since 1.0 + * @version 1.0 + */ + void SetOnTouchListener(OnTouchListener* onTouchListener) + { + onTouchListener_ = onTouchListener; + } + + /** + * @brief Obtains the touch event listener for the view. + * @return Returns the touch event listener. + * @since 1.0 + * @version 1.0 + */ + OnTouchListener*& GetTouchListener() + { + return onTouchListener_; + } + + /** + * @brief Obtains the top-level view based on specified coordinates. + * @param point Indicates the coordinates to specify. + * @param last Indicates the double pointer to the view that contains the specified coordinates. + * @since 1.0 + * @version 1.0 + */ + virtual void GetTargetView(const Point& point, UIView** last); + + /** + * @brief Obtains the current view and target view based on specified coordinates. The obtained current view must + * include the specified coordinates and is a visible top view that can respond to touch events, and the + * obtained target view must be the top view that includes the specified coordinates. + * @param point Indicates the specified coordinates. + * @param current Indicates the double pointer to the current view to obtain. + * nullptr indicates that the target view fails to be obtained. + * @param target Indicates the double pointer to the target view to obtain. + * nullptr indicates that the target view fails to be obtained. + * @since 5.0 + * @version 3.0 + */ + virtual void GetTargetView(const Point& point, UIView** current, UIView** target); + + /** + * @brief Sets the parent view for the view. + * @param parent Indicates the pointer to the parent view to set. + * @since 1.0 + * @version 1.0 + */ + void SetParent(UIView* parent) + { + parent_ = parent; + } + + /** + * @brief Obtains the parent view of the view. + * @return Returns the pointer to the parent view. + * @since 1.0 + * @version 1.0 + */ + UIView* GetParent() const + { + return parent_; + } + + /** + * @brief Sets the next sibling view for the view. + * @param sibling Indicates the pointer to the next sibling view to set. + * @since 1.0 + * @version 1.0 + */ + void SetNextSibling(UIView* sibling) + { + nextSibling_ = sibling; + } + + /** + * @brief Obtains the next sibling view of the view. + * @return Returns the pointer to the next sibling view. + * @since 1.0 + * @version 1.0 + */ + UIView* GetNextSibling() const + { + return nextSibling_; + } + + /** + * @brief Sets whether the view is visible. + * @param visible Specifies whether to set the view visible. Value true means to set the view visible, + * and false means the opposite. + * @since 1.0 + * @version 1.0 + */ + virtual void SetVisible(bool visible) + { + if (visible_ != visible) { + visible_ = visible; + needRedraw_ = true; + Invalidate(); + } + } + + /** + * @brief Checks whether the view is visible. + * @return Returns true if the view is visible; returns false otherwise. + * @since 1.0 + * @version 1.0 + */ + bool IsVisible() const + { + return visible_; + } + + /** + * @brief Sets whether the view is touchable. + * @param touchable Specifies whether to set the view touchable. Value true means to set the view touchable, + * and false means the opposite. + * @since 1.0 + * @version 1.0 + */ + void SetTouchable(bool touch) + { + touchable_ = touch; + } + + /** + * @brief Checks whether the view is touchable. + * @return Returns true if the view is touchable; returns false otherwise. + * @since 1.0 + * @version 1.0 + */ + bool IsTouchable() const + { + return touchable_; + } + + /** + * @brief Sets whether the view is draggable. + * @param draggable Specifies whether to set the view draggable. Value true means to set the view draggable, + * and false means the opposite. + * @since 1.0 + * @version 1.0 + */ + void SetDraggable(bool draggable) + { + draggable_ = draggable; + dragParentInstead_ = !draggable; + } + + /** + * @brief Checks whether the view is draggable. + * @return Returns true if the view is draggable; returns false otherwise. + * @since 1.0 + * @version 1.0 + */ + bool IsDraggable() const + { + return draggable_; + } + + /** + * @brief Sets whether to transfer the drag event to the parent view for processing when the view is being dragged. + * @param dragParentInstead Specifies whether to transfer the event to the parent view for processing. + * Value true means to transfer the event to the parent view for processing, + * and false means the opposite. + * @since 1.0 + * @version 1.0 + */ + void SetDragParentInstead(bool dragParentInstead) + { + dragParentInstead_ = dragParentInstead; + } + + /** + * @brief Obtains whether the view transfers a drag event to the parent view for processing. + * @return Returns true if the view transfers the event to the parent view for processing; + * returns false otherwise. + * @since 1.0 + * @version 1.0 + */ + bool IsDragParentInstead() const + { + return dragParentInstead_; + } + + /** + * @brief Obtains the absolute rectangle area of the view. When the view has deformation such as rotation, + * the rectangle area is the intersection set of the absolute rectangle area and deformation matrix. + * @return Returns the absolute rectangle area. + * @since 1.0 + * @version 1.0 + */ + Rect GetRect() const; + + /** + * @brief Obtains the visible absolute rectangle area of the view. + * @return Returns the visible absolute rectangle area. + * @since 1.0 + * @version 1.0 + */ + Rect GetVisibleRect() const; + + /** + * @brief Obtains the valid absolute rectangle area of the view. The valid area refers to the area where the view + * can be displayed. Generally, the valid area is the same as the visible view area, but they may be + * different in the grid layout. + * @return Returns the valid absolute rectangle area. + * @since 1.0 + * @version 1.0 + */ + Rect GetMaskedRect() const; + + /** + * @brief Obtains the absolute rectangle area of the view. + * @return Returns the absolute rectangle area. + * @since 1.0 + * @version 1.0 + */ + Rect GetOrigRect() const; + + /** + * @brief Obtains the content of the absolute rectangle area of the view. This area excludes padding. + * @return Returns the content of the absolute rectangle area. + * @since 1.0 + * @version 1.0 + */ + virtual Rect GetContentRect(); + + /** + * @brief Obtains the rectangular area of the view relative to the parent view, that is, the rectangular area + * relative to the coordinates of the parent view. + * @return Returns the rectangle area relative to the parent view. + * @since 1.0 + * @version 1.0 + */ + Rect GetRelativeRect() const + { + return rect_; + } + + /** + * @brief Adjusts the size of the visible area. This operation may affect the final display size. + * @param x Indicates the new x-coordinate. + * @param y Indicates the new y-coordinate. + * @param width Indicates the new width. + * @param height Indicates the new height. + * @since 1.0 + * @version 1.0 + */ + void ResizeVisibleArea(int16_t x, int16_t y, int16_t width, int16_t height) + { + if (visibleRect_ == nullptr) { + visibleRect_ = new Rect(); + if (visibleRect_ == nullptr) { + GRAPHIC_LOGE("new Rect fail"); + return; + } + } + visibleRect_->SetWidth(width); + visibleRect_->SetHeight(height); + visibleRect_->SetPosition(x, y); + } + + /** + * @brief Sets the width for the view. + * @param width Indicates the width to set. + * @since 1.0 + * @version 1.0 + */ + virtual void SetWidth(int16_t width) + { + if (GetWidth() != width) { + int16_t newWidth = width + style_->paddingLeft_ + style_->paddingRight_ + + (style_->borderWidth_ * 2); /* 2: left and right border */ + rect_.SetWidth(newWidth); + } + } + + /** + * @brief Sets a percentage that represents the proportion of the view's width to the parent view's width. + * @param widthPercent Indicates the percentage to set, the decimal form of which ranges from 0 to 1. + * @since 5.0 + * @version 3.0 + */ + virtual void SetWidthPercent(float widthPercent); + + /** + * @brief Obtains the width for the view. + * @return Returns the view width. + * @since 1.0 + * @version 1.0 + */ + virtual int16_t GetWidth() + { + return rect_.GetWidth() - (style_->paddingLeft_ + style_->paddingRight_) - + (style_->borderWidth_ * 2); /* 2: left and right border */ + } + + /** + * @brief Sets the height for the view. + * @param height Indicates the height to set. + * @since 1.0 + * @version 1.0 + */ + virtual void SetHeight(int16_t height) + { + if (GetHeight() != height) { + int16_t newHeight = height + style_->paddingTop_ + style_->paddingBottom_ + + (style_->borderWidth_ * 2); /* 2: top and bottom border */ + rect_.SetHeight(newHeight); + } + } + + /** + * @brief Sets a percentage that represents the proportion of the view's hieght to the parent view's hieght. + * @param widthPercent Indicates the percentage to set, the decimal form of which ranges from 0 to 1. + * @since 5.0 + * @version 3.0 + */ + virtual void SetHeightPercent(float heightPercent); + + /** + * @brief Obtains the height for the view. + * @return Returns the view height. + * @since 1.0 + * @version 1.0 + */ + virtual int16_t GetHeight() + { + return rect_.GetHeight() - (style_->paddingTop_ + style_->paddingBottom_) - + (style_->borderWidth_ * 2); /* 2: top and bottom border */ + } + + /** + * @brief Adjusts the size of the view. + * @param width Indicates the new width. + * @param height Indicates the new height. + * @since 1.0 + * @version 1.0 + */ + virtual void Resize(int16_t width, int16_t height) + { + SetWidth(width); + SetHeight(height); + } + + /** + * @brief Adjusts the size of the view based on specified percentages. + * @param widthPercent Indicates the percentage that represents the proportion of the view's width + * to the parent view's width to set, the decimal form of which ranges from 0 to 1. + * @param heightPercent Indicates the percentage that represents the proportion of the view's height + * to the parent view's height to set, the decimal form of which ranges from 0 to 1. + * @since 5.0 + * @version 3.0 + */ + virtual void ResizePercent(float widthPercent, float heightPercent); + + /** + * @brief Sets the x-coordinate for the view. + * @param x Indicates the x-coordinate to set. + * @since 1.0 + * @version 1.0 + */ + virtual void SetX(int16_t x) + { + rect_.SetX(x); + } + + /** + * @brief Sets a percentage that represents the proportion of the view's x-coordinate + * to the parent view's x-coordinate. + * @param xPercent Indicates the percentage to set, the decimal form of which ranges from 0 to 1. + * @since 5.0 + * @version 3.0 + */ + virtual void SetXPercent(float xPercent); + + /** + * @brief Obtains the x-coordinate for the view. + * @return Returns the x-coordinate. + * @since 1.0 + * @version 1.0 + */ + int16_t GetX() const + { + return rect_.GetX(); + } + + /** + * @brief Sets the y-coordinate for the view. + * @param y Indicates the y-coordinate to set. + * @since 1.0 + * @version 1.0 + */ + virtual void SetY(int16_t y) + { + rect_.SetY(y); + } + + /** + * @brief Sets a percentage that represents the proportion of the view's y-coordinate + * to the parent view's y-coordinate. + * @param yPercent Indicates the percentage to set, the decimal form of which ranges from 0 to 1. + * @since 5.0 + * @version 3.0 + */ + virtual void SetYPercent(float yPercent); + + /** + * @brief Obtains the y-coordinate for the view. + * @return Returns the y-coordinate. + * @since 1.0 + * @version 1.0 + */ + int16_t GetY() const + { + return rect_.GetY(); + } + + /** + * @brief Sets the position for the view. + * @param x Indicates the x-coordinate to set. + * @param y Indicates the y-coordinate to set. + * @since 1.0 + * @version 1.0 + */ + virtual void SetPosition(int16_t x, int16_t y) + { + rect_.SetPosition(x, y); + } + + /** + * @brief Sets the position percentages for the view. + * @param xPercent Indicates the percentage that represents the proportion of the view's x-coordinate + * to the parent view's x-coordinate to set, the decimal form of which ranges from 0 to 1. + * @param yPercent Indicates the percentage that represents the proportion of the view's y-coordinate + * to the parent view's y-coordinate to set, the decimal form of which ranges from 0 to 1. + * @since 5.0 + * @version 3.0 + */ + virtual void SetPositionPercent(float xPercent, float yPercent); + + /** + * @brief Adjusts the position and size of the view. + * @param x Indicates the new x-coordinate. + * @param y Indicates the new y-coordinate. + * @param width Indicates the new width. + * @param height Indicates the new height. + * @since 1.0 + * @version 1.0 + */ + virtual void SetPosition(int16_t x, int16_t y, int16_t width, int16_t height) + { + SetPosition(x, y); + SetWidth(width); + SetHeight(height); + } + + /** + * @brief Sets the position and size percentages for the view. + * @param xPercent Indicates the percentage that represents the proportion of the view's x-coordinate + * to the parent view's x-coordinate to set, the decimal form of which ranges from 0 to 1. + * @param yPercent Indicates the percentage that represents the proportion of the view's y-coordinate + * to the parent view's y-coordinate, the decimal form of which ranges from 0 to 1. + * @param widthPercent Indicates the percentage that represents the proportion of the view's width + * to the parent view's width, the decimal form of which ranges from 0 to 1. + * @param heightPercent Indicates the percentage that represents the proportion of the view's height + * to the parent view's height, the decimal form of which ranges from 0 to 1. + * @since 5.0 + * @version 3.0 + */ + virtual void SetPositionPercent(float xPercent, float yPercent, float widthPercent, float heightPercent); + + /** + * @brief Checks whether the view is a container view. + * @return Returns true if the view is a container view; returns false otherwise. + * @since 1.0 + * @version 1.0 + */ + bool IsViewGroup() const + { + return isViewGroup_; + } + + /** + * @brief Sets whether to intercept the drag event. If intercepted, the view does not transfer the drag event to + * the parent view after local processing. + * @param isIntercept Specifies whether to intercept the drag event. Value true means to intercept the drag + * event, and false means the opposite. + * @since 1.0 + * @version 1.0 + */ + void SetIntercept(bool isIntercept) + { + isIntercept_ = isIntercept; + } + + /** + * @brief Sets the affine transformation matrix. + * @param transMap Indicates the transformation matrix. + * @since 1.0 + * @version 1.0 + */ + void SetTransformMap(const TransformMap& transMap); + + /** + * @brief Obtains an affine transformation matrix. + * @return Returns the transform matrix. + * @since 1.0 + * @version 1.0 + */ + TransformMap& GetTransformMap() + { + if (transMap_ == nullptr) { + transMap_ = new TransformMap(); + } + return *transMap_; + } + + /** + * @brief Obtains the child view of a specified ID. + * @return Returns the pointer to the child view. + * @since 1.0 + * @version 1.0 + */ + virtual UIView* GetChildById(const char* id) const + { + return nullptr; + } + + /** + * @brief Sets the view ID. + * @param id Indicates the pointer to the view ID. + * @since 1.0 + * @version 1.0 + */ + void SetViewId(const char* id) + { + id_ = id; + } + + /** + * @brief Obtains the view ID. + * @return Returns the pointer to the view ID. + * @since 1.0 + * @version 1.0 + */ + const char* GetViewId() const + { + return id_; + } + + /** + * @brief Sets the view index. + * @param index Indicates the view index to set. + * @since 1.0 + * @version 1.0 + */ + void SetViewIndex(int16_t index) + { + index_ = index; + } + + /** + * @brief Obtains the view index. + * @return Returns the view index. + * @since 1.0 + * @version 1.0 + */ + int16_t GetViewIndex() const + { + return index_; + } + + /** + * @brief Obtains the view type. + * @return Returns the view type. + * @since 1.0 + * @version 1.0 + */ + virtual UIViewType GetViewType() const + { + return UI_NUMBER_MAX; + } + + /** + * @brief Lays out all child views according to the preset arrangement mode. + * @param needInvalidate Specifies whether to refresh the invalidated area after the layout is complete. + * Value true means to refresh the invalidated area after the layout is complete, + * and false means the opposite. + * @since 1.0 + * @version 1.0 + */ + virtual void LayoutChildren(bool neeInvalidate = false) {} + + /** + * @brief Lays out the view in the center of the parent view. + * @param xOffset Indicates the offset added to the x-axis after the view is placed. A positive number indicates + * the offset to the right, and a negative number indicates the offset to the left. + * @param yOffset Indicates the offset added to the y-axis after the view is placed. A positive number indicates + * the offset to the bottom, and a negative number indicates the offset to the top. + * @since 1.0 + * @version 1.0 + */ + void LayoutCenterOfParent(int16_t xOffSet = 0, int16_t yOffset = 0); + + /** + * @brief Lays out the view on the left of the parent view. + * @param offset Indicates the offset added to the x-axis after the view is placed. A positive number indicates + * the offset to the right, and a negative number indicates the offset to the left. + * @since 1.0 + * @version 1.0 + */ + void LayoutLeftOfParent(int16_t offset = 0); + + /** + * @brief Lays out the view on the right of the parent view. + * @param offset Indicates the offset added to the x-axis after the view is placed. A positive number indicates + * the offset to the left, and a negative number indicates the offset to the right. + * @since 1.0 + * @version 1.0 + */ + void LayoutRightOfParent(int16_t offset = 0); + + /** + * @brief Lays out the view on the top of the parent view. + * @param offset Indicates the offset added to the y-axis after the view is placed. A positive number indicates + * the offset to the bottom, and a negative number indicates the offset to the top. + * @since 1.0 + * @version 1.0 + */ + void LayoutTopOfParent(int16_t offset = 0); + + /** + * @brief Lays out the view on the bottom of the parent view. + * @param offset Indicates the offset added to the y-axis after the view is placed. A positive number indicates + * the offset to the top, and a negative number indicates the offset to the bottom. + * @since 1.0 + * @version 1.0 + */ + void LayoutBottomOfParent(int16_t offset = 0); + + /** + * @brief Aligns the view with the left of a sibling view. + * @param id Indicates the pointer to the ID of the sibling view. + * @param offset Indicates the offset added to the x-axis after the view is placed. A positive number indicates + * the offset to the right, and a negative number indicates the offset to the left. + * @since 1.0 + * @version 1.0 + */ + void AlignLeftToSibling(const char* id, int16_t offset = 0); + + /** + * @brief Aligns the view with the right of a sibling view. + * @param id Indicates the pointer to the ID of the sibling view. + * @param offset Indicates the offset added to the x-axis after the view is placed. A positive number indicates + * the offset to the left, and a negative number indicates the offset to the right. + * @since 1.0 + * @version 1.0 + */ + void AlignRightToSibling(const char* id, int16_t offset = 0); + + /** + * @brief Aligns the view with the top of a sibling view. + * @param id Indicates the pointer to the ID of the sibling view. + * @param offset Indicates the offset added to the y-axis after the view is placed. A positive number indicates + * the offset to the bottom, and a negative number indicates the offset to the top. + * @since 1.0 + * @version 1.0 + */ + void AlignTopToSibling(const char* id, int16_t offset = 0); + + /** + * @brief Aligns the view with the bottom of a sibling view. + * @param id Indicates the pointer to the ID of the sibling view. + * @param offset Indicates the offset added to the y-axis after the view is placed. A positive number indicates + * the offset to the top, and a negative number indicates the offset to the bottom. + * @since 1.0 + * @version 1.0 + */ + void AlignBottomToSibling(const char* id, int16_t offset = 0); + + /** + * @brief Aligns the view with the center of a sibling view in the x-axis. + * @param id Indicates the pointer to the ID of the sibling view. + * @param offset Indicates the offset added to the x-axis after the view is placed. A positive number indicates + * the offset to the right, and a negative number indicates the offset to the left. + * @since 1.0 + * @version 1.0 + */ + void AlignHorCenterToSibling(const char* id, int16_t offset = 0); + + /** + * @brief Aligns the view with the center of a sibling view in the y-axis. + * @param id Indicates the pointer to the ID of the sibling view. + * @param offset Indicates the offset added to the y-axis after the view is placed. A positive number indicates + * the offset to the bottom, and a negative number indicates the offset to the top. + * @since 1.0 + * @version 1.0 + */ + void AlignVerCenterToSibling(const char* id, int16_t offset = 0); + + /** + * @brief Lays out the view on the left of a sibling view. + * @param id Indicates the pointer to the ID of the sibling view. + * @param offset Indicates the offset added to the x-axis after the view is placed. A positive number indicates + * the offset to the left, and a negative number indicates the offset to the right. + * @since 1.0 + * @version 1.0 + */ + void LayoutLeftToSibling(const char* id, int16_t offset = 0); + + /** + * @brief Lays out the view on the right of a sibling view. + * @param id Indicates the pointer to the ID of the sibling view. + * @param offset Indicates the offset added to the x-axis after the view is placed. A positive number indicates + * the offset to the right, and a negative number indicates the offset to the left. + * @since 1.0 + * @version 1.0 + */ + void LayoutRightToSibling(const char* id, int16_t offset = 0); + + /** + * @brief Lays out the view on the above of a sibling view. + * @param id Indicates the pointer to the ID of the sibling view. + * @param offset Indicates the offset added to the y-axis after the view is placed. A positive number indicates + * the offset to the top, and a negative number indicates the offset to the bottom. + * @since 1.0 + * @version 1.0 + */ + void LayoutTopToSibling(const char* id, int16_t offset = 0); + + /** + * @brief Lays out the view on the below of a sibling view. + * @param id Indicates the pointer to the ID of the sibling view. + * @param offset Indicates the offset added to the y-axis after the view is placed. A positive number indicates + * the offset to the bottom, and a negative number indicates the offset to the top. + * @since 1.0 + * @version 1.0 + */ + void LayoutBottomToSibling(const char* id, int16_t offset = 0); + + /** + * @brief Sets the view style. + * @param style Indicates the view style. + * @since 1.0 + * @version 1.0 + */ + virtual void SetStyle(Style& style); + + /** + * @brief Sets a style. + * + * @param key Indicates the key of the style to set. + * @param value Indicates the value matching the key. + * @since 1.0 + * @version 1.0 + */ + virtual void SetStyle(uint8_t key, int64_t value); + + /** + * @brief Obtains the value of a style. + * + * @param key Indicates the key of the style. + * @return Returns the value of the style. + * @since 1.0 + * @version 1.0 + */ + virtual int64_t GetStyle(uint8_t key) const + { + return style_->GetStyle(key); + } + + /** + * @brief Obtains the view style. This function applies to scenarios where the style does not need to be modified, + * which saves memory. + * @return Returns the view style. + * @since 1.0 + * @version 1.0 + */ + const Style& GetStyleConst() const + { + return *style_; + } + + /** + * @brief Sets the opacity for the view. + * + * @param opaScale Indicates the opacity to set. + * @since 1.0 + * @version 1.0 + */ + void SetOpaScale(uint8_t opaScale) + { + opaScale_ = opaScale; + } + + /** + * @brief Obtains the view opacity. + * + * @return Returns the view opacity. + * @since 1.0 + * @version 1.0 + */ + uint8_t GetOpaScale() const + { + return opaScale_; + } + + /** + * @brief Obtains the extra message about a UIView instance. This field is ignored by the graphics + * framework and can be anything you set. + * + * @return Returns the pointer to the extra message about the UIView instance. + * @since 5.0 + * @version 3.0 + */ + ViewExtraMsg* GetExtraMsg() + { + return viewExtraMsg_; + } + + /** + * @brief Sets the extra message about a UIView instance. This field is ignored by the graphics + * framework and can be anything you set. + * + * @param extraMsg Indicates the extra message to set. + * @since 5.0 + * @version 3.0 + */ + void SetExtraMsg(ViewExtraMsg* extraMsg) + { + viewExtraMsg_ = extraMsg; + } + + /** + * @brief Rotates the view. + * @param angle Indicates the rotation angle. + * @param pivot Indicates the coordinates of the rotation pivot. + * @since 5.0 + * @version 3.0 + */ + void Rotate(int16_t angle, const Vector2& pivot); + + /** + * @brief Scales the view. + * + * @param scale Indicates the scale factor on x- and y- axes. + * @param pivot Indicates the scaling pivot. + * @since 5.0 + * @version 3.0 + */ + void Scale(const Vector2& scale, const Vector2& pivot); + + void Translate(const Vector2& trans); + + bool IsTransInvalid(); + + void ResetTransParameter(); + +#if ENABLE_ROTATE_INPUT + /** + * @brief 使组件注册获取焦点 + * + * @since 5.0 + * @version 3.0 + */ + virtual void RequestFocus(); + + /** + * @brief 使组件失去焦点 + * + * @since 5.0 + * @version 3.0 + */ + virtual void ClearFocus(); +#endif + +protected: + bool touchable_ : 1; + bool visible_ : 1; + bool draggable_ : 1; + bool dragParentInstead_ : 1; + bool isViewGroup_ : 1; + bool needRedraw_ : 1; + bool styleAllocFlag_ : 1; + bool isIntercept_ : 1; + uint8_t opaScale_; + int16_t index_; + const char* id_; + UIView* parent_; + UIView* nextSibling_; + Style* style_; + TransformMap* transMap_; + OnClickListener* onClickListener_; + OnLongPressListener* onLongPressListener_; + OnDragListener* onDragListener_; + OnTouchListener* onTouchListener_; +#if ENABLE_ROTATE_INPUT + OnRotateListener* onRotateListener_; +#endif + ViewExtraMsg* viewExtraMsg_; + + uint8_t GetMixOpaScale(); + bool IsInvalid(float percent); + +private: + Rect rect_; + Rect* visibleRect_; + void SetupThemeStyles(); +}; +} // namespace OHOS +#endif // GRAPHIC_LITE_UI_VIEW_H diff --git a/interfaces/kits/components/ui_view_group.h b/interfaces/kits/components/ui_view_group.h new file mode 100755 index 0000000..88c4542 --- /dev/null +++ b/interfaces/kits/components/ui_view_group.h @@ -0,0 +1,265 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +/** + * @addtogroup UI_Components + * @{ + * + * @brief Defines UI components such as buttons, texts, images, lists, and progress bars. + * + * @since 1.0 + * @version 1.0 + */ + +/** + * @file ui_view_group.h + * + * @brief Declares a view group. + * + * @since 1.0 + * @version 1.0 + */ + +#ifndef GRAPHIC_LITE_UI_VIEW_GROUP_H +#define GRAPHIC_LITE_UI_VIEW_GROUP_H + +#include "components/ui_view.h" + +namespace OHOS { +/** + * @brief Represents a view group that consists of its child views. + * + * The child views can be added to, inserted in, and removed from the view group. + * Child views that are added later are displayed at the upper layer of this view group. + * All child views are stored in a linked list. + * + * @since 1.0 + * @version 1.0 + */ +class UIViewGroup : public UIView { +public: + /** + * @brief A default constructor used to create a UIViewGroup instance. + * + * @since 1.0 + * @version 1.0 + */ + UIViewGroup(); + + /** + * @brief A destructor used to delete the UIViewGroup instance. + * + * @since 1.0 + * @version 1.0 + */ + virtual ~UIViewGroup(); + + /** + * @brief Obtains the view type. + * + * @return Returns UI_VIEW_GROUP, as defined in {@link UIViewType}. + * @since 1.0 + * @version 1.0 + */ + UIViewType GetViewType() const override + { + return UI_VIEW_GROUP; + } + + /** + * @brief Adds a child view. + * + * @param view Indicates the pointer to the child view to add. + * @since 1.0 + * @version 1.0 + */ + virtual void Add(UIView* view); + + /** + * @brief Inserts a new child view behind the current one. + * + * @param prevView Indicates the pointer to the current child view, previous to the new child view to insert. + * @param view Indicates the pointer to the new child view to insert. + * @since 1.0 + * @version 1.0 + */ + virtual void Insert(UIView* prevView, UIView* insertView); + + /** + * @brief Removes a child view. + * + * @param view Indicates the pointer to the child view to remove. + * @since 1.0 + * @version 1.0 + */ + virtual void Remove(UIView* view); + + /** + * @brief Removes all child views. + * + * @since 1.0 + * @version 1.0 + */ + virtual void RemoveAll(); + + /** + * @brief Obtains the target child view that is visible and can respond to touch events based on given coordinates. + * + * @param point Indicates the given coordinates. + * @param last Indicates the double pointer to the target view. nullptr indicates that the target + * view is not available. + * @since 1.0 + * @version 1.0 + */ + virtual void GetTargetView(const Point& point, UIView** last) override; + + /** + * @brief Obtains the current view and target view based on specified coordinates. The obtained current view + * must include the specified coordinates and is a visible top view that can respond to touch events, + * and the obtained target view must be the top view that includes the specified coordinates. + * + * @param point Indicates the specified coordinates. + * @param current Indicates the double pointer to the current view to obtain. + * nullptr indicates that the target view fails to be obtained. + * @param target Indicates the double pointer to the target view to obtain. + * nullptr indicates that the target view fails to be obtained. + * @since 5.0 + * @version 3.0 + */ + virtual void GetTargetView(const Point& point, UIView** current, UIView** target) override; + + /** + * @brief Moves all child views. + * + * @param x Indicates the offset distance by which this view group is moved on the x-axis. + * @param y Indicates the offset distance by which this view group is moved on the y-axis. + * @since 1.0 + * @version 1.0 + */ + virtual void MoveChildByOffset(int16_t x, int16_t y); + + /** + * @brief Obtains the first child view in this view group. + * + * @return Returns the first child view. + * @since 1.0 + * @version 1.0 + */ + UIView* GetChildrenHead() const + { + return childrenHead_; + } + + /** + * @brief Obtains the last child view in this view group. + * + * @return Returns the last child view. + * @since 1.0 + * @version 1.0 + */ + UIView* GetChildrenTail() const + { + return childrenTail_; + } + + /** + * @brief Sets whether this view group is intercepted upon touch events. + * + * @param flag Specifies whether this view group is intercepted upon touch events. true indicates that + * this view group is intercepted upon touch events, and false indicates the opposite case. + * @since 1.0 + * @version 1.0 + */ + void SetDisallowIntercept(bool flag) + { + disallowIntercept_ = flag; + } + + /** + * @brief Obtains the target child view with a specified ID. + * + * @param id Indicates the pointer to the ID of the target child view. + * @return Returns the target child view if available; returns nullptr otherwise. + * @since 1.0 + * @version 1.0 + */ + UIView* GetChildById(const char* id) const override; + + /** + * @brief Sets whether the size of this view group is adaptive to that of all child views. + * + * @param state Specifies whether the size of this view group is adaptive to that of all child views. + * true indicates automatic adaption is enabled, and false indicates the opposite case. + * @since 1.0 + * @version 1.0 + */ + void SetAutoSize(bool state) + { + isAutoSize_ = state; + } + +protected: + /** + * @brief Obtains the rectangle area of a new view group after being adaptive to the size of all child views. + * + * @return Returns the rectangle area of the new view group. + * @since 1.0 + * @version 1.0 + */ + Rect GetAllChildRelativeRect() const; + + /** + * @brief Performs operations needed after a child view is added or removed. + * + * @since 1.0 + * @version 1.0 + */ + virtual void OnChildChanged() {}; + + /** + * @brief Indicates the pointer to the first child view of this view group. + */ + UIView* childrenHead_; + + /** + * @brief Indicates the pointer to the last child view of this view group. + */ + UIView* childrenTail_; + + /** + * @brief Represents the number of child views. + */ + uint16_t childrenNum_; + + /** + * @brief Specifies the sliding state of this view group. + */ + bool isDragging_; + + /** + * @brief Specifies whether this view group is intercepted upon touch events. + */ + bool disallowIntercept_; + + /** + * @brief Specifies whether the size of this view group is adaptive to that of all child views. + */ + bool isAutoSize_; + +private: + void AutoResize(); +}; +} // namespace OHOS +#endif // GRAPHIC_LITE_UI_VIEW_GROUP_H diff --git a/interfaces/kits/dfx/event_injector.h b/interfaces/kits/dfx/event_injector.h new file mode 100755 index 0000000..2d20123 --- /dev/null +++ b/interfaces/kits/dfx/event_injector.h @@ -0,0 +1,191 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +/** + * @addtogroup UI_DFX + * @{ + * + * @brief Provides test and analysis capabilities, such as stimulating input events and viewing information about a + * Document Object Model (DOM) tree. + * + * @since 1.0 + * @version 1.0 + */ + +/** + * @file event_injector.h + * + * @brief Declares functions for simulating input events. + * + * @since 1.0 + * @version 1.0 + */ +#ifndef GRAPHIC_LITE_EVENT_INJECTOR_H +#define GRAPHIC_LITE_EVENT_INJECTOR_H + +#include "graphic_config.h" +#if ENABLE_DEBUG +#include "heap_base.h" +#include "input_event_info.h" +namespace OHOS { +/** + * @ Enumerates the event types. + */ +enum class EventDataType { + /** Point event */ + POINT_TYPE, + /** Key event */ + KEY_TYPE, + /** Other events */ + OTHERS +}; +class PointEventInjector; +class KeyEventInjector; + +/** + * @brief Manages all types of simulated input events, registers and unregisters event injectors, and simulates + * input events. + * + * @since 1.0 + * @version 1.0 + */ +class EventInjector : public HeapBase { +public: + /** + * @brief Obtains a singleton EventInjector instance. + * + * @return Returns the EventInjector instance. + * @since 1.0 + * @version 1.0 + */ + static EventInjector* GetInstance() + { + static EventInjector instance; + return &instance; + } + + /** + * @brief Registers an event injector of a specified type. + * + * @param type Indicates the event type. For details, see {@link EventDataType}. + * @return Returns true if the operation is successful; returns false otherwise. + * @since 1.0 + * @version 1.0 + */ + bool RegisterEventInjector(EventDataType type); + + /** + * @brief Unregisters an event injector of a specified type. + * + * @param type Indicates the event type. For details, see {@link EventDataType}. + * @since 1.0 + * @version 1.0 + */ + void UnregisterEventInjector(EventDataType type); + + /** + * @brief Checks whether the event injector of a specified type is registered. + * + * @param type Indicates the event type. For details, see {@link EventDataType}. + * @return Returns true if the device is registered; returns false otherwise. + * @since 1.0 + * @version 1.0 + */ + bool IsEventInjectorRegistered(EventDataType type) const; + + /** + * @brief Uses a data array of a specified length to simulate an input event of a specified type. + * + * @param dataArray Indicates the pointer to the data array used for simulating the event. + * @param arrayLength Indicates the length of the data array. + * @param type Indicates the event type. For details, see {@link EventDataType}. + * @return Returns true if the operation is successful; returns false otherwise. + * @since 1.0 + * @version 1.0 + */ + bool SetInjectEvent(const DeviceData* dataArray, uint16_t arrayLength, EventDataType type); + + /** + * @brief Stimulates a click event. + * + * @param clickPoint Indicates the coordinates of the click point. + * @return Returns true if the operation is successful; returns false otherwise. + * @since 3.0 + * @version 5.0 + */ + bool SetClickEvent(const Point& clickPoint); + + /** + * @brief Stimulates a long press event. + * + * @param longPressPoint Indicates the coordinates of the long press point. + * @return Returns true if the operation is successful; returns false otherwise. + * @since 3.0 + * @version 5.0 + */ + bool SetLongPressEvent(const Point& longPressPoint); + + /** + * @brief Stimulates a drag event that occurs between two points. + * + * @param startPoint Indicates the coordinates of the start point. + * @param endPoint Indicates the coordinates of the end point. + * @param dragTime Indicates the duration of dragging from the start point to the end point, in milliseconds. + * The value range is [2, 499] x {@link INDEV_READ_PERIOD}. + * The shorter the duration is, the faster the sliding is. + * + * @return Returns true if the operation is successful; returns false otherwise. + * @since 3.0 + * @version 5.0 + */ + bool SetDragEvent(const Point& startPoint, const Point& endPoint, uint32_t dragTime); + + /** + * @brief Simulates a key event. + * + * @param keyId Indicates the key ID. + * @param state Indicates the key state. For details, see {@link InputDevice}. + * @return Returns true if the operation is successful; returns false otherwise. + * @since 3.0 + * @version 5.0 + */ + bool SetKeyEvent(uint16_t keyId, uint16_t state); + +#if ENABLE_WINDOW + /** + * @brief Set id of mock window. + * + * @param windowId id of mock window + * + * @since 3.0 + * @version 5.0 + */ + void SetWindowId(uint8_t windowId); +#endif +private: + EventInjector() : pointEventInjector_(nullptr), keyEventInjector_(nullptr) {} + virtual ~EventInjector(); + + EventInjector(const EventInjector&) = delete; + EventInjector& operator=(const EventInjector&) = delete; + EventInjector(EventInjector&&) = delete; + EventInjector& operator=(EventInjector&&) = delete; + + PointEventInjector* pointEventInjector_; + KeyEventInjector* keyEventInjector_; +}; +} // namespace OHOS +#endif // ENABLE_DEBUG +#endif // GRAPHIC_LITE_EVENT_INJECTOR_H diff --git a/interfaces/kits/dfx/ui_dump_dom_tree.h b/interfaces/kits/dfx/ui_dump_dom_tree.h new file mode 100755 index 0000000..3b94471 --- /dev/null +++ b/interfaces/kits/dfx/ui_dump_dom_tree.h @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +/** + * @addtogroup UI_DFX + * @{ + * + * @brief Provides test and analysis capabilities, such as stimulating input events and viewing information about a + * Document Object Model (DOM) tree. + * + * @since 1.0 + * @version 1.0 + */ + +/** + * @file ui_dump_dom_tree.h + * + * @brief Declares a function for exporting information about a Document Object Model (DOM) tree or DOM node. + * + * @since 1.0 + * @version 1.0 + */ +#ifndef GRAPHIC_LITE_UI_DUMP_DOM_TREE_H +#define GRAPHIC_LITE_UI_DUMP_DOM_TREE_H + +#include "graphic_config.h" +#include "heap_base.h" +#if ENABLE_DEBUG +#include "cJSON.h" +#include "components/ui_view.h" +#endif // ENABLE_DEBUG +namespace OHOS { +#if ENABLE_DEBUG +/** + * @brief Enumerates export modes. + */ +enum DumpMode { + /** DOM tree */ + DUMP_TREE, + /** DOM node */ + DUMP_NODE +}; +#endif // ENABLE_DEBUG + +/** + * @brief Provides functions for exporting information about a specified DOM node or information about the DOM tree + * starting from a specified DOM node. + * + * @since 1.0 + * @version 1.0 + */ +class UIDumpDomTree : public HeapBase { +public: + /** + * @brief Obtains an instance in singleton pattern. + * + * @return Returns the function instance for exporting DOM information. + * @since 1.0 + * @version 1.0 + */ + static UIDumpDomTree* GetInstance() + { + static UIDumpDomTree instance; + return &instance; + } + + /** + * @brief Exports information about a DOM tree starting from a specified DOM node and saves the information to + * a specified path. + * + * @param id Indicates the pointer to the DOM node ID. + * @param path Indicates the pointer to the specified path. + * @return Returns true if the operation is successful; returns false otherwise. + * @since 1.0 + * @version 1.0 + */ + bool DumpDomTree(const char* id, const char* path); + + /** + * @brief Exports information about a DOM tree starting from a specified DOM node and saves the information to + * the default path. + * The default path is {@link DEFAULT_DUMP_DOM_TREE_PATH}. + * + * @param id Indicates the pointer to the DOM node ID. + * @return Returns true if the operation is successful; returns false otherwise. + * @since 1.0 + * @version 1.0 + */ + bool DumpDomTree(const char* id) + { + return DumpDomTree(id, nullptr); + } + + /** + * @brief Exports information about a specified DOM node. + * + * @param id Indicates the pointer to the DOM node ID. + * @return Returns a character string about the DOM node information. The character string memory is released by + * invoking cJSON_free(). + * @since 1.0 + * @version 1.0 + */ + char* DumpDomNode(const char* id); + +private: +#if ENABLE_DEBUG + bool searchFlag_; // Search flag, set when find the view with right id. + bool allocErrorFlag_; // Alloc error flag, set when cJSON fails to allocate memory. + char* pJson_; // Pointer for returning cJSON string. + cJSON* rootJson_; // Root pointer of cJSON structure. + const char* path_; + + void DumpJsonById(UIView* view, const char* id, DumpMode mode); + + void AddNameField(UIViewType type, cJSON* usr) const; + void AddCommonField(UIView* view, cJSON* usr) const; + void AddImageViewSpecialField(const UIView* view, cJSON* usr) const; + void AddSpecialField(const UIView* view, cJSON* usr) const; + void OutputDomNode(UIView* view); + void OutputDomTree(UIView* view, cJSON* usr); + bool WriteDumpFile() const; + + UIDumpDomTree() + : searchFlag_(false), + allocErrorFlag_(false), + pJson_(nullptr), + rootJson_(nullptr), + path_(DEFAULT_DUMP_DOM_TREE_PATH) + { + } +#else + UIDumpDomTree() {} +#endif // ENABLE_DEBUG + virtual ~UIDumpDomTree() {} + + UIDumpDomTree(const UIDumpDomTree&) = delete; + UIDumpDomTree& operator=(const UIDumpDomTree&) = delete; + UIDumpDomTree(UIDumpDomTree&&) = delete; + UIDumpDomTree& operator=(UIDumpDomTree&&) = delete; +}; +} // namespace OHOS +#endif // GRAPHIC_LITE_UI_DUMP_DOM_TREE_H diff --git a/interfaces/kits/dfx/ui_screenshot.h b/interfaces/kits/dfx/ui_screenshot.h new file mode 100755 index 0000000..27e1225 --- /dev/null +++ b/interfaces/kits/dfx/ui_screenshot.h @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +/** + * @addtogroup UI_DFX + * @{ + * + * @brief Provides test and analysis capabilities, such as stimulating input events and viewing information about a + * Document Object Model (DOM) tree. + * + * @since 1.0 + * @version 1.0 + */ + +/** + * @file ui_screenshot.h + * + * @brief Declares the screenshot function. + * + * @since 1.0 + * @version 1.0 + */ +#ifndef GRAPHIC_LITE_UI_SCREENSHOT_H +#define GRAPHIC_LITE_UI_SCREENSHOT_H + +#include "graphic_config.h" + +#if ENABLE_DEBUG +#include "heap_base.h" + +namespace OHOS { +/** + * @brief Provides callback functions for screenshot events. + * + * @since 1.0 + * @version 1.0 + */ +class UIScreenshotListener; + +/** + * @brief Provides external screenshot functions. + * + * @since 1.0 + * @version 1.0 + */ +class UIScreenshot : public HeapBase { +public: + /** + * @brief Obtains an instance in singleton pattern. + * + * @return Returns the screenshot function instance. + * @since 1.0 + * @version 1.0 + */ + static UIScreenshot* GetInstance() + { + static UIScreenshot instance; + return &instance; + } + + /** + * @brief Takes a screenshot and saves it to a file. + * + * @param path Indicates the pointer to the path for storing the screenshot file. + * @return Returns true if the operation is successful; returns false otherwise. + * @since 1.0 + * @version 1.0 + */ + bool ScreenshotToFile(const char* path); + +private: + UIScreenshotListener* screenshotListener_; + + UIScreenshot() : screenshotListener_(nullptr) {} + virtual ~UIScreenshot(); + + UIScreenshot(const UIScreenshot&) = delete; + UIScreenshot& operator=(const UIScreenshot&) = delete; + UIScreenshot(UIScreenshot&&) = delete; + UIScreenshot& operator=(UIScreenshot&&) = delete; +}; +} // namespace OHOS +#endif // ENABLE_DEBUG +#endif // GRAPHIC_LITE_UI_SCREENSHOT_H diff --git a/interfaces/kits/events/aod_callback.h b/interfaces/kits/events/aod_callback.h new file mode 100755 index 0000000..7f0698d --- /dev/null +++ b/interfaces/kits/events/aod_callback.h @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +/** + * @addtogroup UI_Events + * @{ + * + * @brief Defines UI events, such as press, click and drag events. + * + * @since 1.0 + * @version 1.0 + */ + +/** + * @file aod_callback.h + * + * @brief Defines the callback for the touch event notification in screen-off mode. + * + * @since 1.0 + * @version 1.0 + */ + +#include "components/ui_view.h" +#include "graphic_config.h" + +#ifndef AOD_CALLBACK_H +#define AOD_CALLBACK_H + +#if ENABLE_AOD +namespace OHOS { +/** + * @brief Called when a tap event occurs on the state machine. The screen-off display module will be notified of this + * event. + * + * @param view Indicates the view instance where the tap event occurs. + */ +void OnClickEventHappen(UIView& view); + +/** + * @brief Called when a sliding end event occurs on the state machine. The screen-off display module will be notified of + * this event. + * + * @param view Indicates the view instance where the sliding end event occurs. + */ +void OnDragEndEventHappen(UIView& view); + +/** + * @brief Called when a press event occurs on the state machine. The screen-off display module will be notified of this + * event. + * + * @param view the attached view + */ +void OnLongPressEventHappen(UIView& view); +} // namespace OHOS +#endif // ENABLE_AOD +#endif // AOD_CALLBACK_H diff --git a/interfaces/kits/events/cancel_event.h b/interfaces/kits/events/cancel_event.h new file mode 100755 index 0000000..d05c43a --- /dev/null +++ b/interfaces/kits/events/cancel_event.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +/** + * @addtogroup UI_Events + * @{ + * + * @brief Defines UI events, such as press, click and drag events. + * + * @since 1.0 + * @version 1.0 + */ + +/** + * @file cancel_event.h + * + * @brief Declares a cancel event, which usually occurs when the target view changes due to user sliding. For example, + this event is triggered if you, after pressing a button, does not release the button but slides. + * + * @since 1.0 + * @version 1.0 + */ + +#ifndef GRAPHIC_LITE_CANCEL_EVENT_H +#define GRAPHIC_LITE_CANCEL_EVENT_H + +#include "event.h" + +namespace OHOS { +/** + * @brief Defines a cancel event, which usually occurs when the target view changes due to user sliding. For example, + this event is triggered if you, after pressing a button, does not release the button but slides. + * @since 1.0 + * @version 1.0 + */ +class CancelEvent : public Event { +public: + /** + * @brief A constructor used to create a CancelEvent instance. + * @param pos Indicates the position where the cancel event occurs. + * @since 1.0 + * @version 1.0 + */ + CancelEvent(const Point& pos) : Event(pos) {} + + /** + * @brief A destructor used to delete the CancelEvent instance. + * @since 1.0 + * @version 1.0 + */ + virtual ~CancelEvent() {} +}; +} // namespace OHOS +#endif // GRAPHIC_LITE_CANCEL_EVENT_H diff --git a/interfaces/kits/events/click_event.h b/interfaces/kits/events/click_event.h new file mode 100755 index 0000000..f29d8e8 --- /dev/null +++ b/interfaces/kits/events/click_event.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +/** + * @addtogroup UI_Events + * @{ + * + * @brief Defines UI events, such as press, click and drag events. + * + * @since 1.0 + * @version 1.0 + */ + +/** + * @file click_event.h + * + * @brief Declares a click event, which indicates that a finger is pressed on the screen and then + * lifted within 1 second. + * + * @since 1.0 + * @version 1.0 + */ + +#ifndef GRAPHIC_LITE_CLICK_EVENT_H +#define GRAPHIC_LITE_CLICK_EVENT_H + +#include "event.h" + +namespace OHOS { +/** + * @brief Defines a click event, which indicates that a finger is pressed on the screen and then lifted within 1 second. + * + * @since 1.0 + * @version 1.0 + */ +class ClickEvent : public Event { +public: + /** + * @brief A constructor used to create a ClickEvent instance. + * @param pos Indicates the position where the click event occurs. + * @since 1.0 + * @version 1.0 + */ + ClickEvent(const Point& pos) : Event(pos) {} + + /** + * @brief A destructor used to delete the ClickEvent instance. + * @since 1.0 + * @version 1.0 + */ + virtual ~ClickEvent() {} +}; +} // namespace OHOS +#endif // GRAPHIC_LITE_CLICK_EVENT_H diff --git a/interfaces/kits/events/drag_event.h b/interfaces/kits/events/drag_event.h new file mode 100755 index 0000000..2bd11ef --- /dev/null +++ b/interfaces/kits/events/drag_event.h @@ -0,0 +1,173 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +/** + * @addtogroup UI_Events + * @{ + * + * @brief Defines UI events, such as press, click and drag events. + * + * @since 1.0 + * @version 1.0 + */ + +/** + * @file drag_event.h + * + * @brief Declares a drag event, which indicates a certain movement (more than 10 pixels) after a view is pressed. + * + * @since 1.0 + * @version 1.0 + */ + +#ifndef GRAPHIC_LITE_DRAG_EVENT_H +#define GRAPHIC_LITE_DRAG_EVENT_H + +#include "event.h" + +namespace OHOS { +/** + * @brief Defines a drag event, which indicates a certain movement (more than 10 pixels) after a view is pressed. + * + * @since 1.0 + * @version 1.0 + */ +class DragEvent : public Event { +public: + /** + * @brief A constructor used to create a DragEvent instance. + * @param newPos Indicates the new position in the drag event. + * @param lastPos Indicates the last position in the drag event. + * @param totalLen Indicates the distance that the view has been dragged, including the movement on the x-axis + * and y-axis. + * @since 1.0 + * @version 1.0 + */ + DragEvent(const Point& newPos, const Point& lastPos, const Point& totalLen) : Event(newPos) + { + lastPos_ = lastPos; + startPos_.x = newPos.x - totalLen.x; + startPos_.y = newPos.y - totalLen.y; + preLastPos_ = lastPos; + deltaX_ = newPos.x - lastPos.x; + deltaY_ = newPos.y - lastPos.y; + } + + /** + * @brief A destructor used to delete the DragEvent instance. + * @since 1.0 + * @version 1.0 + */ + virtual ~DragEvent() {} + + /** + * @brief Obtains the coordinates of the last position in the drag event. + * @return Returns the coordinates of the last position. + * @since 1.0 + * @version 1.0 + */ + const Point& GetLastPoint() const + { + return lastPos_; + } + + /** + * @brief Obtains the start coordinates in the drag event. + * @return Returns the start coordinates. + * @since 1.0 + * @version 1.0 + */ + const Point& GetStartPoint() const + { + return startPos_; + } + + /** + * @brief Sets the coordinates of the stay position before the last position in the drag event. + * @param preLastPos Indicates the coordinates of the stay position to set. + * @since 1.0 + * @version 1.0 + */ + void SetPreLastPoint(const Point& preLastPos) + { + preLastPos_ = preLastPos; + } + + /** + * @brief Obtains the coordinates of the stay position before the last position in the drag event. + * @return Returns the coordinates of the stay position. + * @since 1.0 + * @version 1.0 + */ + const Point& GetPreLastPoint() const + { + return preLastPos_; + } + + /** + * @brief Obtains the direction in the drag event. + * @return Returns the direction. Available values are as follows: + * 0 indicates dragging from left to right. + * 1 indicates dragging from right to left. + * 2 indicates dragging from top to bottom. + * 3 indicates dragging from bottom to top. + * @since 1.0 + * @version 1.0 + */ + uint8_t GetDragDirection() const + { + if (MATH_ABS(curPos_.x - startPos_.x) >= MATH_ABS(curPos_.y - startPos_.y)) { + return (curPos_.x > startPos_.x) ? DIRECTION_LEFT_TO_RIGHT : DIRECTION_RIGHT_TO_LEFT; + } else { + return (curPos_.y > startPos_.y) ? DIRECTION_TOP_TO_BOTTOM : DIRECTION_BOTTOM_TO_TOP; + } + } + + /** + * @brief Obtains the difference between the current position and the last position of the view in the x-axis. + * @return Returns the different in the x-aix. + * @since 1.0 + * @version 1.0 + */ + int16_t GetDeltaX() const + { + return deltaX_; + } + + /** + * @brief Obtains the difference between the current position and the last position of the view in the y-axis. + * @return Returns the different in the y-aix. + * @since 1.0 + * @version 1.0 + */ + int16_t GetDeltaY() const + { + return deltaY_; + } + + static constexpr uint8_t DIRECTION_LEFT_TO_RIGHT = 0; + static constexpr uint8_t DIRECTION_RIGHT_TO_LEFT = 1; + static constexpr uint8_t DIRECTION_TOP_TO_BOTTOM = 2; + static constexpr uint8_t DIRECTION_BOTTOM_TO_TOP = 3; + +private: + Point lastPos_; + Point startPos_; + Point preLastPos_; + int16_t deltaX_; + int16_t deltaY_; +}; +} // namespace OHOS +#endif // GRAPHIC_LITE_DRAG_EVENT_H diff --git a/interfaces/kits/events/event.h b/interfaces/kits/events/event.h new file mode 100755 index 0000000..b92f57c --- /dev/null +++ b/interfaces/kits/events/event.h @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +/** + * @addtogroup UI_Events + * @{ + * + * @brief Defines UI events, such as press, click and drag events. + * + * @since 1.0 + * @version 1.0 + */ + +/** + * @file event.h + * + * @brief Declares the base class of a user input event and provides functions to record information such as + * the event position and timestamp. + * + * @since 1.0 + * @version 1.0 + */ + +#ifndef GRAPHIC_LITE_EVENT_H +#define GRAPHIC_LITE_EVENT_H + +#include "geometry2d.h" +#include "graphic_types.h" + +namespace OHOS { +class UIView; +/** + * @brief Defines the base class of a user input event and provides functions to record information such as + * the event position and timestamp. + * + * @since 1.0 + * @version 1.0 + */ +class Event : public HeapBase { +public: + /** + * @brief A default constructor used to create an Event instance. + * @since 1.0 + * @version 1.0 + */ + Event(); + + /** + * @brief A constructor used to create an Event instance. + * @param pos Indicates the position where the event occurs. + * @since 1.0 + * @version 1.0 + */ + Event(const Point& curPos); + + /** + * @brief A destructor used to delete the Event instance. + * @since 1.0 + * @version 1.0 + */ + virtual ~Event() {} + + /** + * @brief Obtains the position where an event occurs. + * @return Returns the position. + * @since 1.0 + * @version 1.0 + */ + const Point& GetCurrentPos() const + { + return curPos_; + } + + /** + * @brief Obtains the timestamp when an event occurs. + * @return Returns the timestamp. + * @since 1.0 + * @version 1.0 + */ + const TimeType& GetTimeStamp() const + { + return timeStamp_; + } + + /** + * @brief Sets the timestamp when an event occurs. + * @param timeStamp Indicates the timestamp of the event to set. + * @since 1.0 + * @version 1.0 + */ + void SetTimeStamp(const TimeType& timeStamp) + { + timeStamp_ = timeStamp; + } +protected: + TimeType timeStamp_; + Point curPos_; + UIView* targetView_ = nullptr; + UIView* currentView_ = nullptr; +}; +} // namespace OHOS +#endif // GRAPHIC_LITE_EVENT_H diff --git a/interfaces/kits/events/key_event.h b/interfaces/kits/events/key_event.h new file mode 100755 index 0000000..555edbc --- /dev/null +++ b/interfaces/kits/events/key_event.h @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +/** + * @addtogroup UI_Events + * @{ + * + * @brief Defines UI events, such as press, click and drag events. + * + * @since 1.0 + * @version 1.0 + */ + +/** + * @file key_event.h + * + * @brief Declares a key event, which indicates that a physical button is pressed or released. + * + * @since 1.0 + * @version 1.0 + */ + +#ifndef GRAPHIC_LITE_KEY_EVENT_H +#define GRAPHIC_LITE_KEY_EVENT_H + +#include "event.h" + +namespace OHOS { +constexpr uint16_t INVALID_KEY_STATE = UINT16_MAX; + +/** + * @brief Defines a key event, which indicates that a physical button is pressed or released. + * + * @since 1.0 + * @version 1.0 + */ +class KeyEvent : public Event { +public: + KeyEvent() = delete; + + /** + * @brief A constructor used to create a KeyEvent instance. + * @param keyId Indicates the key ID. + * @param state Indicates the key state. + * @since 1.0 + * @version 1.0 + */ + KeyEvent(uint16_t keyId, uint16_t state) : keyId_(keyId), state_(state) {} + + /** + * @brief A destructor used to delete the KeyEvent instance. + * @since 1.0 + * @version 1.0 + */ + ~KeyEvent() {} + + /** + * @brief Obtains the key ID. + * @since 1.0 + * @version 1.0 + */ + uint16_t GetKeyId() const + { + return keyId_; + } + + /** + * @brief Obtains the key state. + * @since 1.0 + * @version 1.0 + */ + uint16_t GetState() const + { + return state_; + } + +private: + uint16_t keyId_; + uint16_t state_; +}; +} // namespace OHOS +#endif // GRAPHIC_LITE_KEY_EVENT_H diff --git a/interfaces/kits/events/long_press_event.h b/interfaces/kits/events/long_press_event.h new file mode 100755 index 0000000..a0c53f5 --- /dev/null +++ b/interfaces/kits/events/long_press_event.h @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +/** + * @addtogroup UI_Events + * @{ + * + * @brief Defines UI events, such as press, click and drag events. + * + * @since 1.0 + * @version 1.0 + */ + +/** + * @file long_press_event.h + * + * @brief Declares a long-press event, which indicates that the finger is not raised or moved within 1 second + * after a view is pressed. + * + * @since 1.0 + * @version 1.0 + */ + +#ifndef GRAPHIC_LITE_LONG_PRESS_EVENT_H +#define GRAPHIC_LITE_LONG_PRESS_EVENT_H + +#include "event.h" + +namespace OHOS { +/** + * @brief Defines a long-press event, which indicates that the finger is not raised or moved within 1 second + * after a view is pressed. + * + * @since 1.0 + * @version 1.0 + */ +class LongPressEvent : public Event { +public: + /** + * @brief A constructor used to create a LongPressEvent instance. + * @param pos Indicates the position where the long-press event occurs. + * @param timeStamp Indicates the time stamp when the long-press event occurs. + * @since 1.0 + * @version 1.0 + */ + LongPressEvent(const Point& pos, const TimeType& timeStamp) : Event(pos) + { + timeStamp_ = timeStamp; + } + + /** + * @brief A destructor used to delete the LongPressEvent instance. + * @since 1.0 + * @version 1.0 + */ + virtual ~LongPressEvent() {} +}; +} // namespace OHOS +#endif // GRAPHIC_LITE_LONG_PRESS_EVENT_H diff --git a/interfaces/kits/events/press_event.h b/interfaces/kits/events/press_event.h new file mode 100755 index 0000000..f598658 --- /dev/null +++ b/interfaces/kits/events/press_event.h @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef GRAPHIC_LITE_PRESS_EVENT_H +#define GRAPHIC_LITE_PRESS_EVENT_H + +/** + * @addtogroup UI_Events + * @{ + * + * @brief Defines UI events, such as press, click and drag events. + * + * @since 1.0 + * @version 1.0 + */ + +/** + * @file press_event.h + * + * @brief Declares a touch event, which indicates that the touchscreen or mouse is pressed. + * + * @since 1.0 + * @version 1.0 + */ + +#include "event.h" + +namespace OHOS { +/** + * @brief Defines a touch event, which indicates that the touchscreen or mouse is pressed. + * + * @since 1.0 + * @version 1.0 + */ +class PressEvent : public Event { +public: + /** + * @brief A constructor used to create a PressEvent instance. + * @param pos Indicates the position where the press event occurs. + * @since 1.0 + * @version 1.0 + */ + PressEvent(const Point& pos) : Event(pos) {} + + /** + * @brief A destructor used to delete the PressEvent instance. + * @since 1.0 + * @version 1.0 + */ + virtual ~PressEvent() {} +}; +} // namespace OHOS +#endif // GRAPHIC_LITE_PRESS_EVENT_H diff --git a/interfaces/kits/events/release_event.h b/interfaces/kits/events/release_event.h new file mode 100755 index 0000000..931cc8d --- /dev/null +++ b/interfaces/kits/events/release_event.h @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +/** + * @addtogroup UI_Events + * @{ + * + * @brief Defines UI events, such as press, click and drag events. + * + * @since 1.0 + * @version 1.0 + */ + +/** + * @file release_event.h + * + * @brief Declares a release event, which indicates that the touchscreen or mouse is released. + * + * @since 1.0 + * @version 1.0 + */ + +#ifndef GRAPHIC_LITE_RELEASE_EVENT_H +#define GRAPHIC_LITE_RELEASE_EVENT_H + +#include "event.h" + +namespace OHOS { +/** + * @brief Defines a release event, which indicates that the touchscreen or mouse is released. + * + * @since 1.0 + * @version 1.0 + */ +class ReleaseEvent : public Event { +public: + /** + * @brief A constructor used to create a ReleaseEvent instance. + * @param pos Indicates the position where the release event occurs. + * @since 1.0 + * @version 1.0 + */ + ReleaseEvent(const Point& pos) : Event(pos) {} + + /** + * @brief A destructor used to delete the ReleaseEvent instance. + * @since 1.0 + * @version 1.0 + */ + virtual ~ReleaseEvent() {} +}; +} // namespace OHOS +#endif // GRAPHIC_LITE_RELEASE_EVENT_H diff --git a/interfaces/kits/events/rotate_event.h b/interfaces/kits/events/rotate_event.h new file mode 100755 index 0000000..14da4ce --- /dev/null +++ b/interfaces/kits/events/rotate_event.h @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef GRAPHIC_LITE_ROTATE_EVENT_H +#define GRAPHIC_LITE_ROTATE_EVENT_H +/** + * @addtogroup Graphic + * @{ + * + * @brief Defines a lightweight graphics system that provides basic UI and container views, + * including buttons, images, labels, lists, animators, scroll views, swipe views, and layouts. + * This system also provides the Design for X (DFX) capability to implement features such as + * view rendering, animation, and input event distribution. + * + * @since 1.0 + * @version 1.0 + */ + +/** + * @file rotate_event.h + * + * @brief ת¼RotateEventťӲ + * + * @since 5.0 + * @version 3.0 + */ + +#include "event.h" + +namespace OHOS { +/** + * @brief ת¼RotateEventťӲ + * + * @since 5.0 + * @version 3.0 + */ +class RotateEvent : public Event { +public: + RotateEvent() = delete; + + /** + * @brief ת¼RotateEventʵĹ캯. + * @param rotate shortתֵ + * + * @since 5.0 + * @version 3.0 + */ + RotateEvent(int16_t rotate) : rotate_(-rotate * ROTATE_SENSITIVITY) {} // תת + + ~RotateEvent() {}; + + /** + * @brief ȡתֵ + * @return תֵ + * + * @since 5.0 + * @version 3.0 + */ + int16_t GetRotate() const + { + return rotate_; + } + +private: + int16_t rotate_; +}; +} // namespace OHOS +#endif // GRAPHIC_LITE_ROTATE_EVENT_H \ No newline at end of file diff --git a/interfaces/kits/events/virtual_device_event.h b/interfaces/kits/events/virtual_device_event.h new file mode 100755 index 0000000..80333d4 --- /dev/null +++ b/interfaces/kits/events/virtual_device_event.h @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +/** + * @addtogroup UI_Events + * @{ + * + * @brief Defines UI events, such as press, click and drag events. + * + * @since 1.0 + * @version 1.0 + */ + +/** + * @file virtual_device_event.h + * + * @brief Declares a virtual device event, which is used to receive a customized input event and call back + * the listening function registered. + * + * @since 1.0 + * @version 1.0 + */ + +#ifndef GRAPHIC_LITE_VIRTUAL_DEVICE_EVENT_H +#define GRAPHIC_LITE_VIRTUAL_DEVICE_EVENT_H + +#include "event.h" + +namespace OHOS { +/** + * @brief Defines a virtual device event, which is used to receive a customized input event and call back + * the listening function registered. + * + * @since 1.0 + * @version 1.0 + */ +class VirtualDeviceEvent : public Event { +public: + VirtualDeviceEvent() = delete; + + /** + * @brief A constructor used to create a VirtualDeviceEvent instance. + * + * @param type Indicates the virtual device type. The options are AOD and PRIVATE. + * @param value Indicates the virtual event value. + * @since 1.0 + * @version 1.0 + */ + VirtualDeviceEvent(uint16_t type, uint16_t value) : type_(type), state_(value) {} + + /** + * @brief A destructor used to delete the VirtualDeviceEvent instance. + * + * @since 1.0 + * @version 1.0 + */ + ~VirtualDeviceEvent() {} + + /** + * @brief Enumerates virtual device types. + * + */ + enum DeviceType { + AOD, // Standby event + PRIVATE, // Other customized events + }; + + /** + * @brief Obtains the type of the virtual device. + * + * @return Returns the type. + * @since 1.0 + * @version 1.0 + */ + uint16_t GetType() const + { + return type_; + } + + /** + * @brief Obtains the state of the virtual event. + * + * @return Returns the state. + * @since 1.0 + * @version 1.0 + */ + uint16_t GetState() const + { + return state_; + } + +private: + uint16_t type_; + uint16_t state_; + static constexpr uint16_t INVALID_VIRTUAL_INPUT_STATE = UINT16_MAX; +}; +} // namespace OHOS +#endif // GRAPHIC_LITE_VIRTUAL_DEVICE_EVENT_H diff --git a/interfaces/kits/font/base_font.h b/interfaces/kits/font/base_font.h new file mode 100755 index 0000000..fe055f6 --- /dev/null +++ b/interfaces/kits/font/base_font.h @@ -0,0 +1,222 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef BASE_FONT +#define BASE_FONT +#include "font/ui_font_header.h" +#include "graphic_config.h" + +namespace OHOS { +class BaseFont : public HeapBase { +public: + BaseFont() : fontId_(0), ramAddr_(0), ramLen_(0) {} + virtual ~BaseFont() {} + + /** + * @brief Indicates whether the current font library is a vector font library. + * @return uint8_t: 0 BitmapFont 1 VectorFont + */ + virtual bool IsVectorFont() const = 0; + + /** + * @brief Set font by id + * + * @param fontid [in] the font id + * @param size [in] the font size + * @return int8_t: -1 failed, 0 success + */ + virtual int8_t SetCurrentFontId(uint8_t fontId, uint8_t size) = 0; + + /** + * @brief Get height for specific font + * + * @return uint16_t + */ + virtual uint16_t GetHeight() = 0; + + /** + * @brief Get font id + * + * @param ttfName + * @param size 0: invaild size + * @return uint8_t + */ + virtual uint8_t GetFontId(const char* ttfName, uint8_t size) const = 0; + + /** + * @brief Get width + * + * @param unicode + * @return int16_t + */ + virtual int16_t GetWidth(uint32_t unicode, uint8_t fontId) = 0; + + virtual int32_t OpenVectorFont(uint8_t ttfId) + { + return -1; + } + /** + * @brief Get bitmap for specific unicode + * + * @param unicode + * @return uint8_t* + */ + virtual uint8_t* GetBitmap(uint32_t unicode, GlyphNode& glyphNode, uint8_t fontId) = 0; + + /** + * @brief Get font header + * + * @param fontHeader + * @return int8_t + */ + virtual int8_t GetCurrentFontHeader(FontHeader& fontHeader) = 0; + + /** + * @brief Get the glyph node + * + * @param unicode + * @param glyphNode + * @param isGlyph + * @return int8_t + */ + virtual int8_t GetGlyphNode(uint32_t unicode, GlyphNode& glyphNode) = 0; + virtual uint8_t GetFontWeight(uint8_t fontId) = 0; + + virtual int8_t SetCurrentLangId(uint8_t langId) + { + return 0; + } + + virtual uint8_t GetCurrentLangId() const + { + return GetTotalLangId(); + } + + int8_t GetDefaultParamByLangId(uint8_t langId, LangTextParam** pParam) const; + + /** + * @brief Get the Font Shaping Property + * @param text [in] the content + * @param ttfId [out] the ttf id + * @param fontId [in] the font id + * @param size [in] the font size + * @return uint8_t: needShaping property + */ + virtual uint8_t GetShapingFontId(char* text, uint8_t& ttfId, uint32_t& script, uint8_t fontId, uint8_t size) const + { + return 0; + } + + /** + * @brief Set the Font Path + * + * @param dpath + * @param spath + * @return int8_t + */ + virtual int8_t SetFontPath(const char* dpath, const char* spath) = 0; + + virtual int8_t GetFontVersion(char* dVersion, uint8_t dLen, char* sVersion, uint8_t sLen) const + { + return INVALID_RET_VALUE; + } + + /** + * @brief Get the text in utf-8 format + * + * @param textId + * @param utf8Addr + * @param utf8Len + * @return int8_t + */ + virtual int8_t GetTextUtf8(uint16_t textId, uint8_t** utf8Addr, uint16_t& utf8Len) const + { + return 0; + } + + /** + * @brief Get the ttfId + * @param fontId [in] the font id + * @param size [in] the font size + * @return uint8_t: ttfId property + */ + virtual uint8_t GetFontTtfId(uint8_t fontId, uint8_t size) const + { + return 0; + } + + virtual const UITextLanguageFontParam* GetFontInfo(uint8_t fontId) const + { + return nullptr; + } + + virtual uint8_t RegisterFontInfo(const char* ttfName, uint8_t shaping) + { + return 0; + } + + virtual uint8_t RegisterFontInfo(const UITextLanguageFontParam* fontsTable, uint8_t num) + { + return 0; + } + + virtual uint8_t UnregisterFontInfo(const char* ttfName) + { + return 0; + } + + virtual uint8_t UnregisterFontInfo(const UITextLanguageFontParam* fontsTable, uint8_t num) + { + return 0; + } + + virtual int8_t GetWildCardStaticStr(uint16_t textId, + UITextWildcardStaticType type, + uint8_t** strAddr, + uint16_t& strLen) const + { + return 0; + } + + virtual int8_t GetCodePoints(uint16_t textId, uint32_t** codePoints, uint16_t& codePointsNum) const + { + return 0; + } + + virtual int8_t GetTextParam(uint16_t textId, UITextLanguageTextParam& param) const + { + return 0; + } + + /** + * @brief Get current font id + * + * @return uint8_t + */ + void SetBaseFontId(uint8_t fontId); + uint8_t GetBaseFontId(); + void SetRamAddr(uintptr_t ramAddr); + uintptr_t GetRamAddr(); + uint32_t GetRamLen(); + void SetRamLen(uint32_t ramLen); + void SetPsramMemory(uintptr_t psramAddr, uint32_t psramLen); + +private: + uint8_t fontId_; + uintptr_t ramAddr_; + uint32_t ramLen_; +}; +} // namespace OHOS +#endif /* UI_BASE_FONT_H */ diff --git a/interfaces/kits/font/ui_font.h b/interfaces/kits/font/ui_font.h new file mode 100755 index 0000000..e1ef36c --- /dev/null +++ b/interfaces/kits/font/ui_font.h @@ -0,0 +1,238 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ +#ifndef UI_FONT_H +#define UI_FONT_H +#include "font/base_font.h" + +namespace OHOS { +class UIFont : public HeapBase { +public: + UIFont(const UIFont &) = delete; + UIFont& operator=(const UIFont &) = delete; + + /** + * @brief judge whether you need shaping for text + * + * @param text means input text + * @param ttfId font index + * @param script shaping script + * @param fontId font index + * @param size font size + * @return int8_t Shaping mode + */ + uint8_t GetShapingFontId(char* text, uint8_t& ttfId, uint32_t& script, uint8_t fontId, uint8_t size) const + { + return instance_->GetShapingFontId(text, ttfId, script, fontId, size); + } + + /** + * @brief Set font id + * + * @param fontId + * @param size + * @return int8_t + */ + int8_t SetCurrentFontId(uint8_t fontId, uint8_t size = 0) + { + return instance_->SetCurrentFontId(fontId, size); + } + + /** + * @brief Get width of the letter + * + * @param unicode: [in] unicode or glyph index according to isGlyph param + * @param shapingId: [in] + * @return uint16_t: the letter width + */ + uint16_t GetWidth(uint32_t unicode, uint8_t shapingId); + + /** + * @brief Get height for specific font + * + * @return uint16_t + */ + uint16_t GetHeight() + { + return instance_->GetHeight(); + } + + /** + * @brief Get the font weight + * @param fontId + * @return uint8_t: fontWeight + */ + uint8_t GetFontWeight(uint8_t fontId) + { + return instance_->GetFontWeight(fontId); + } + + /** + * @brief Get font header + * + * @param fontHeader + * @return int8_t + */ + int8_t GetCurrentFontHeader(FontHeader& fontHeader) + { + return instance_->GetCurrentFontHeader(fontHeader); + } + + /** + * @brief Get font id + * + * @param name + * @param size + * @return uint8_t + */ + uint8_t GetFontId(const char* name, uint8_t size = 0) + { + return instance_->GetFontId(name, size); + } + + /** + * @brief Set the cache start address + * + * @param psramAddr + * @param psramLen + */ + void SetPsramMemory(uintptr_t psramAddr, uint32_t psramLen) + { + instance_->SetPsramMemory(psramAddr, psramLen); + } + + /** + * @brief Get bitmap for specific unicode + * + * @param unicode + * @return uint8_t* + */ + uint8_t* GetBitmap(uint32_t unicode, GlyphNode& glyphNode, uint8_t shapingFont); + + /** + * @brief Indicates whether the current font library is a vector font library. + * @return uint8_t: 0 BitmapFont 1 VectorFont + */ + bool IsVectorFont() + { + return instance_->IsVectorFont(); + } + + /** + * @brief Get current font id + * + * @return uint8_t + */ + uint8_t GetCurrentFontId() + { + return instance_->GetBaseFontId(); + } + + int8_t SetCurrentLangId(uint8_t langId) + { + return instance_->SetCurrentLangId(langId); + } + + uint8_t GetCurrentLangId() const + { + return instance_->GetCurrentLangId(); + } + + int8_t GetDefaultParamByLangId(uint8_t langId, LangTextParam** pParam) const + { + return instance_->GetDefaultParamByLangId(langId, pParam); + } + + int8_t GetTextUtf8(uint16_t textId, uint8_t** utf8Addr, uint16_t& utf8Len) const + { + return instance_->GetTextUtf8(textId, utf8Addr, utf8Len); + } + + uint8_t GetFontTtfId(uint8_t fontId, uint8_t size) const + { + return instance_->GetFontTtfId(fontId, size); + } + + int32_t OpenVectorFont(uint8_t ttfId) + { + return instance_->OpenVectorFont(ttfId); + } + + const UITextLanguageFontParam* GetFontInfo(uint8_t fontId) const + { + return instance_->GetFontInfo(fontId); + } + + int8_t SetFontPath(const char* dpath, const char* spath) + { + return instance_->SetFontPath(dpath, spath); + } + + int8_t GetFontVersion(char* dVersion, uint8_t dLen, char* sVersion, uint8_t sLen) const + { + return instance_->GetFontVersion(dVersion, dLen, sVersion, sLen); + } + + uint8_t RegisterFontInfo(const char* ttfName, uint8_t shaping = 0) + { + return instance_->RegisterFontInfo(ttfName, shaping); + } + + uint8_t RegisterFontInfo(const UITextLanguageFontParam* fontsTable, uint8_t num) + { + return instance_->RegisterFontInfo(fontsTable, num); + } + + uint8_t UnregisterFontInfo(const char* ttfName) + { + return instance_->UnregisterFontInfo(ttfName); + } + + uint8_t UnregisterFontInfo(const UITextLanguageFontParam* fontsTable, uint8_t num) + { + return instance_->UnregisterFontInfo(fontsTable, num); + } + + int8_t GetTextParam(uint16_t textId, UITextLanguageTextParam& param) const + { + return instance_->GetTextParam(textId, param); + } + + int8_t GetWildCardStaticStr(uint16_t textId, UITextWildcardStaticType type, + uint8_t** strAddr, uint16_t& strLen) const + { + return instance_->GetWildCardStaticStr(textId, type, strAddr, strLen); + } + + int8_t GetCodePoints(uint16_t textId, uint32_t** codePoints, uint16_t& codePointsNum) const + { + return instance_->GetCodePoints(textId, codePoints, codePointsNum); + } + + static UIFont* GetInstance(); + void SetFont(BaseFont* font); + +private: + UIFont(); + /** + * @brief Destroy the UIFontFactor object + * + */ + ~UIFont(); + + BaseFont* instance_; + BaseFont* defaultInstance_; +}; +} // namespace OHOS +#endif diff --git a/interfaces/kits/font/ui_font_header.h b/interfaces/kits/font/ui_font_header.h new file mode 100755 index 0000000..38370eb --- /dev/null +++ b/interfaces/kits/font/ui_font_header.h @@ -0,0 +1,412 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef GRAPHIC_LITE_UI_FONT_HEADER_H +#define GRAPHIC_LITE_UI_FONT_HEADER_H + +#include +#include "common/text.h" +namespace OHOS { +#pragma pack(1) + +enum UITextWildcardStaticType : uint8_t { TEXT_STATIC_STR1 = 0, TEXT_STATIC_STR2, TEXT_STATIC_STR3 }; + +struct UITextLanguageTextParam { + uint16_t textId; + uint8_t fontId; + uint8_t align : 2; // UITextLanguageAlignment + uint8_t direct : 1; // UITextLanguageDirect + uint8_t shaping : 1; + uint8_t wildCard1 : 1; + uint8_t wildCard2 : 1; + uint8_t reserve : 2; + uint32_t strOff1; + uint16_t strLen1; + uint16_t strLen2; + uint16_t strLen3; + uint32_t codePointsOff; + uint16_t codePointsLen; +}; // UITextLanguageTextParam + +// bin header +constexpr uint8_t FONT_VERSION_OFFSET = 0; +constexpr uint8_t FONT_VERSION_LEN = 10; +constexpr uint8_t FONT_MAGIC_NUM_OFFSET = FONT_VERSION_OFFSET + FONT_VERSION_LEN; +constexpr uint8_t FONT_MAGIC_NUM_LEN = 6; +constexpr uint8_t FONT_NUMBER_OFFSET = FONT_MAGIC_NUM_OFFSET + FONT_MAGIC_NUM_LEN; +constexpr uint8_t FONT_NUMBER_LEN = 2; +constexpr uint8_t BIN_HEAD_RES_OFFSET = FONT_NUMBER_OFFSET + FONT_NUMBER_LEN; +constexpr uint8_t BIN_HEAD_RES_LEN = 2; +constexpr uint8_t FONT_DATA_OFFSET = BIN_HEAD_RES_OFFSET + BIN_HEAD_RES_LEN; +constexpr uint8_t BIN_HEAD_TOTAL_LEN = FONT_VERSION_LEN + FONT_MAGIC_NUM_LEN + FONT_NUMBER_LEN + BIN_HEAD_RES_LEN; + +// font header +constexpr uint8_t FONT_ID_OFFSET = 0; +constexpr uint8_t FONT_ID_LEN = 1; +constexpr uint8_t GLYPH_NUM_OFFSET = FONT_ID_OFFSET + FONT_ID_LEN; +constexpr uint8_t GLYPH_NUM_LEN = 2; +constexpr uint8_t FONT_HEIGHT_OFFSET = GLYPH_NUM_OFFSET + GLYPH_NUM_LEN; +constexpr uint8_t FONT_HEIGHT_LEN = 2; +constexpr uint8_t FONT_ASCEND_OFFSET = FONT_HEIGHT_OFFSET + FONT_HEIGHT_LEN; +constexpr uint8_t FONT_ASCEND_LEN = 2; +constexpr uint8_t FONT_DESCEND_OFFSET = FONT_ASCEND_OFFSET + FONT_ASCEND_LEN; +constexpr uint8_t FONT_DESCEND_LEN = 2; +constexpr uint8_t FONT_INDEX_OFF_OFFSET = FONT_DESCEND_OFFSET + FONT_DESCEND_LEN; +constexpr uint8_t FONT_INDEX_OFF_LEN = 4; +constexpr uint8_t FONT_INDEX_LEN_OFFSET = FONT_INDEX_OFF_OFFSET + FONT_INDEX_OFF_LEN; +constexpr uint8_t FONT_INDEX_LEN_LEN = 4; +constexpr uint8_t GLYPH_OFF_OFFSET = FONT_INDEX_LEN_OFFSET + FONT_INDEX_LEN_LEN; +constexpr uint8_t GLYPH_OFF_LEN = 4; +constexpr uint8_t GLYPH_LEN_OFFSET = GLYPH_OFF_OFFSET + GLYPH_OFF_LEN; +constexpr uint8_t GLYPH_LEN_LEN = 4; +constexpr uint8_t FONT_HEAD_RES_OFFSET = GLYPH_LEN_OFFSET + GLYPH_LEN_LEN; +constexpr uint8_t FONT_HEAD_RES_LEN = 2; +constexpr uint8_t FONT_HEAD_TOTAL_LEN = FONT_ID_LEN + GLYPH_NUM_LEN + FONT_HEIGHT_LEN + FONT_ASCEND_LEN + + FONT_DESCEND_LEN + GLYPH_OFF_LEN + GLYPH_LEN_LEN + FONT_HEAD_RES_LEN; + +// glyph header, internal using, not write to bin file +constexpr uint8_t FONT_G_HEIGHT_OFFSET = 0; +constexpr uint8_t FONT_G_HEIGHT_LEN = 2; +constexpr uint8_t GLYPH_G_NUM_OFFSET = FONT_G_HEIGHT_OFFSET + FONT_G_HEIGHT_LEN; +constexpr uint8_t GLYPH_G_NUM_LEN = 2; +constexpr uint8_t GLYPH_G_ASCEND_OFFSET = GLYPH_G_NUM_OFFSET + GLYPH_G_NUM_LEN; +constexpr uint8_t GLYPH_G_ASCEND_LEN = 2; +constexpr uint8_t GLYPH_G_DESCEND_OFFSET = GLYPH_G_ASCEND_OFFSET + GLYPH_G_ASCEND_LEN; +constexpr uint8_t GLYPH_G_DESCEND_LEN = 2; +constexpr uint8_t GLYPH_G_INDEX_OFF_OFFSET = GLYPH_G_DESCEND_OFFSET + GLYPH_G_DESCEND_LEN; +constexpr uint8_t GLYPH_G_INDEX_OFF_LEN = 4; +constexpr uint8_t GLYPH_G_INDEX_LEN_OFFSET = GLYPH_G_INDEX_OFF_OFFSET + GLYPH_G_INDEX_OFF_LEN; +constexpr uint8_t GLYPH_G_INDEX_LEN_LEN = 4; +constexpr uint8_t GLYPH_G_OFF_OFFSET = GLYPH_G_INDEX_LEN_OFFSET + GLYPH_G_INDEX_LEN_LEN; +constexpr uint8_t GLYPH_G_OFF_LEN = 4; +constexpr uint8_t GLYPH_G_LEN_OFFSET = GLYPH_G_OFF_OFFSET + GLYPH_G_OFF_LEN; +constexpr uint8_t GLYPH_G_LEN_LEN = 4; +constexpr uint8_t FONT_G_HEAD_TOTAL_LEN = + FONT_G_HEIGHT_LEN + GLYPH_G_NUM_LEN + GLYPH_G_ASCEND_LEN + GLYPH_G_DESCEND_LEN + GLYPH_G_OFF_LEN + GLYPH_G_LEN_LEN; + +// glyph node +constexpr uint8_t GLYPH_UNICODE_OFFSET = GLYPH_G_NUM_OFFSET + GLYPH_G_NUM_LEN; +constexpr uint8_t GLYPH_UNICODE_LEN = 4; +constexpr uint8_t GLYPH_LEFT_OFFSET = GLYPH_UNICODE_OFFSET + GLYPH_UNICODE_LEN; +constexpr uint8_t GLYPH_LEFT_LEN = 2; +constexpr uint8_t GLYPH_TOP_OFFSET = GLYPH_LEFT_OFFSET + GLYPH_LEFT_LEN; +constexpr uint8_t GLYPH_TOP_LEN = 2; +constexpr uint8_t GLYPH_ADVANCE_OFFSET = GLYPH_TOP_OFFSET + GLYPH_TOP_LEN; +constexpr uint8_t GLYPH_ADVANCE_LEN = 2; +constexpr uint8_t GLYPH_COLS_OFFSET = GLYPH_ADVANCE_OFFSET + GLYPH_ADVANCE_LEN; +constexpr uint8_t GLYPH_COLS_LEN = 2; +constexpr uint8_t GLYPH_ROWS_OFFSET = GLYPH_COLS_OFFSET + GLYPH_COLS_LEN; +constexpr uint8_t GLYPH_ROWS_LEN = 2; +constexpr uint8_t GLYPH_DATA_OFF_OFFSET = GLYPH_ROWS_OFFSET + GLYPH_ROWS_LEN; +constexpr uint8_t GLYPH_DATA_OFF_LEN = 4; +constexpr uint8_t GLYPH_KERN_OFF_OFFSET = GLYPH_DATA_OFF_OFFSET + GLYPH_DATA_OFF_LEN; +constexpr uint8_t GLYPH_KERN_OFF_LEN = 4; +constexpr uint8_t GLYPH_KERN_SIZE_OFFSET = GLYPH_KERN_OFF_OFFSET + GLYPH_KERN_OFF_LEN; +constexpr uint8_t GLYPH_KERN_SIZE_LEN = 2; +constexpr uint8_t GLYPH_HEAD_RES_OFFSET = GLYPH_KERN_SIZE_OFFSET + GLYPH_KERN_SIZE_LEN; +constexpr uint8_t GLYPH_HEAD_RES_LEN = 2; +constexpr uint8_t GLYPH_HEAD_TOTAL_LEN = GLYPH_UNICODE_LEN + GLYPH_LEFT_LEN + GLYPH_TOP_LEN + GLYPH_ADVANCE_LEN + + GLYPH_COLS_LEN + GLYPH_ROWS_LEN + GLYPH_DATA_OFF_LEN + GLYPH_KERN_OFF_LEN + + GLYPH_KERN_SIZE_LEN + GLYPH_HEAD_RES_LEN; + +// language texts table header +constexpr uint8_t LANG_TEXTS_PARAM_OFF = 0; +constexpr uint8_t LANG_TEXTS_PARAM_LEN = 4; +constexpr uint8_t LANG_TEXTS_UTF8P_OFF = LANG_TEXTS_PARAM_OFF + LANG_TEXTS_PARAM_LEN; +constexpr uint8_t LANG_TEXTS_UTF8P_LEN = 4; +constexpr uint8_t LANG_TEXTS_UTF8_OFF = LANG_TEXTS_UTF8P_OFF + LANG_TEXTS_UTF8P_LEN; +constexpr uint8_t LANG_TEXTS_UTF8_LEN = 4; +constexpr uint8_t LANG_TEXTS_TOTAL_LEN = LANG_TEXTS_PARAM_LEN + LANG_TEXTS_UTF8P_LEN + LANG_TEXTS_UTF8_LEN; + +// language texts utf-8 param header +constexpr uint8_t LANG_UTF8_PARAM_TOTAL_LEN = 8; // 4B offset + 4B len + +// language bin header +constexpr uint8_t LANG_OFFSET_OFF = 0; +constexpr uint8_t LANG_OFFSET_LEN = 4; +constexpr uint8_t LANG_SIZE_OFF = LANG_OFFSET_OFF + LANG_OFFSET_LEN; +constexpr uint8_t LANG_SIZE_LEN = 4; +constexpr uint8_t LANG_HEAD_TOTAL_LEN = LANG_OFFSET_LEN + LANG_SIZE_LEN; + +// dynamic font +constexpr uint32_t GLYPH_HEADER_LENGTH = 0xD7C00; // 860 K, almost 33870 glyph header +constexpr uint32_t FONT_HEADER_LENGTH = FONT_HEAD_TOTAL_LEN * 150; // 150 font, almost 3K +constexpr uint32_t DYNAMIC_FONT_HEADER_TOTAL_LENGTH = GLYPH_HEADER_LENGTH + FONT_HEADER_LENGTH; + +// static font psram +constexpr uint32_t UTF8_PARAM_LENGTH = LANG_UTF8_PARAM_TOTAL_LEN * 100; // 100 lang, almost 1K +constexpr uint32_t STATIC_PARAM_LENGTH = sizeof(UITextLanguageTextParam) * 3218; // 3218 texts, 44K +constexpr uint32_t STATIC_UTF8_LENGTH = 0xC800; // 50 * 1024 = 50K +constexpr uint32_t STATIC_FONT_HEADER_LENGTH = FONT_HEAD_TOTAL_LEN * 150; // 150 font, almost 3K +constexpr uint32_t STATIC_GLYPH_HEADER_LENGTH = 0x15C00; // 87K, almost 26 * 3426 glyph header +constexpr uint32_t STATIC_FONT_HEADER_TOTAL_LENGTH = UTF8_PARAM_LENGTH + STATIC_PARAM_LENGTH + STATIC_UTF8_LENGTH + + STATIC_FONT_HEADER_LENGTH + STATIC_GLYPH_HEADER_LENGTH; + +constexpr uint8_t MAX_CACHE_CHAR_NUMBER = 50; // cache 50 letters +constexpr uint32_t DYNAMIC_ONE_CHAR_LENGTH = 0x5000; // 20 K means w200:h200:bpp4, 200 x 200 / 2 + +// 50 * 20K = 1000K +constexpr uint32_t DYNAMIC_TEXT_CACHE_LENGTH = MAX_CACHE_CHAR_NUMBER * DYNAMIC_ONE_CHAR_LENGTH; +constexpr uint32_t MIN_FONT_PSRAM_LENGTH = 0x380000; + +// text shaping psram +constexpr uint32_t SHAPING_TTF_TABLE_LENGTH = 0x4B000; // 307K +constexpr uint32_t SHAPING_WORD_DICT_LENGTH = 0xD000; // 53K +constexpr uint32_t SHAPING_CACHE_LENGTH = 0x50000; // 328K +constexpr uint32_t MIN_SHAPING_PSRAM_LENGTH = + SHAPING_TTF_TABLE_LENGTH + SHAPING_WORD_DICT_LENGTH + SHAPING_CACHE_LENGTH + HARFBUZ_CACHE_LENGTH; + +// other definition +constexpr uint8_t FONT_DPI = 100; +constexpr uint8_t FONT_PIXEL_IN_POINT = 64; +constexpr uint8_t BPP_BIT_1 = 1; +constexpr uint8_t BPP_MASK_1 = 7; +constexpr uint8_t BPP_SHIFT_1 = 3; +constexpr uint8_t BPP_MASK_NUM_1 = 0x80; +constexpr uint8_t BPP_BIT_2 = 2; +constexpr uint8_t BPP_MASK_2 = 3; +constexpr uint8_t BPP_SHIFT_2 = 2; +constexpr uint8_t BPP_MASK_NUM_2 = 0xC0; +constexpr uint8_t BPP_BIT_4 = 4; +constexpr uint8_t BPP_MASK_4 = 1; +constexpr uint8_t BPP_SHIFT_4 = 1; +constexpr uint8_t BPP_MASK_NUM_4 = 0xF0; +constexpr uint8_t BPP_BIT_8 = 8; +constexpr uint32_t DEFAULT_FONT_SIZE = 10; +constexpr uint32_t MAX_CHAR_MB_LEN = 16; +constexpr uint32_t MAX_CHAR_NUM = 512; +constexpr uint8_t BITS_PER_BYTE = 8; +constexpr uint8_t BITS_MASK_IN_BYTE = 7; +constexpr uint32_t MAX_MONO_ADVANCE = 128; +constexpr uint8_t BIT0 = 0; +constexpr uint8_t BIT1 = 1; +constexpr uint8_t BIT2 = 2; +constexpr uint8_t BIT3 = 3; +constexpr uint8_t BIT4 = 4; +constexpr uint8_t BIT5 = 5; +constexpr uint8_t BIT6 = 6; +constexpr uint8_t BIT7 = 7; +constexpr uint8_t BIT8 = 8; +constexpr uint8_t BIT12 = 12; +constexpr uint8_t BIT18 = 18; +constexpr uint8_t GLYPH_KERN_ITEM_LEN = 2; +constexpr uint8_t UTF_TO_UNICODE_MASK1 = 0x80; +constexpr uint8_t UTF_TO_UNICODE_MASK2 = 0xC0; +constexpr uint8_t UTF_TO_UNICODE_MASK3 = 0xE0; +constexpr uint8_t UTF_TO_UNICODE_MASK4 = 0xF0; +constexpr uint8_t UTF_TO_UNICODE_MASK5 = 0xF8; +constexpr uint8_t UTF_TO_UNICODE_MASK6 = 0x3F; +constexpr uint8_t UTF_TO_UNICODE_MASK7 = 0x1F; +constexpr uint8_t UTF_TO_UNICODE_MASK8 = 0x07; +constexpr uint8_t UTF_TO_UNICODE_MASK9 = 0x0F; +constexpr uint8_t MAX_FILE_NAME_LEN = 255; +constexpr uint8_t GPU_FONT_ALIGN_BIT = 16; +constexpr uint8_t INVALID_UCHAR_ID = 0xFF; +constexpr uint16_t INVALID_USHORT_ID = 0xFFFF; +constexpr uint32_t INVALID_UINT_ID = 0xFFFFFFFF; +constexpr int8_t INVALID_RET_VALUE = -1; +constexpr int8_t RET_VALUE_OK = 0; +constexpr const char* FONT_MAGIC_NUMBER = const_cast("OHOS."); + +/** + * @brief struct BinHeader for font + * refer to ui_font.h + */ +struct BinHeader { + char fontVersion[FONT_VERSION_LEN]; // FONT_VERSION_OFFSET + char fontMagic[FONT_MAGIC_NUM_LEN]; // FONT_MAGIC_NUM_OFFSET + uint16_t fontNum; // FONT_NUMBER_OFFSET + uint16_t reserve; // BIN_HEAD_RES_OFFSET +}; + +/** + * @brief struct FontHeader + * refer to ui_font.h + */ +struct FontHeader { + uint8_t fontId; // FONT_ID_OFFSET + uint16_t glyphNum; // GLYPH_NUM_OFFSET + uint16_t fontHeight; // FONT_HEIGHT_OFFSET + int16_t ascender; // FONT_ASCEND_LEN + int16_t descender; // FONT_DESCEND_LEN + uint32_t indexOffset; + uint32_t indexLen; + uint32_t glyphOffset; // GLYPH_G_OFF_OFFSET + uint32_t glyphLen; // GLYPH_OFF_OFFSET + uint16_t reserve; // GLYPH_LEN_OFFSET +}; + +/** + * @brief struct GlyphHeader for font, font tool using, not for bin file + * refer to ui_font.h + */ +struct GlyphHeader { + uint16_t fontHeight; // FONT_G_HEIGHT_OFFSET + uint16_t glyphNum; // GLYPH_G_NUM_OFFSET + int16_t ascender; // GLYPH_G_ASCEND_LEN + int16_t descender; // GLYPH_G_DESCEND_LEN + uint32_t indexOffset; + uint32_t indexLen; + uint32_t glyphOffset; // GLYPH_G_OFF_OFFSET + uint32_t glyphLen; // GLYPH_G_LEN_OFFSET +}; + +/** + * @brief struct GlyphNode for font + * refer to ui_font.h + */ +struct GlyphNode { + uint32_t unicode; // GLYPH_UNICODE_OFFSET + int16_t left; // GLYPH_LEFT_OFFSET + int16_t top; // GLYPH_TOP_OFFSET + uint16_t advance; // GLYPH_ADVANCE_OFFSET + uint16_t cols; // GLYPH_COLS_OFFSET + uint16_t rows; // GLYPH_ROWS_OFFSET + uint32_t dataOff; // GLYPH_DATA_OFF_OFFSET + uint32_t kernOff; // GLYPH_KERN_OFF_OFFSET + uint16_t kernSize; // GLYPH_KERN_SIZE_OFFSET + uint16_t reserve; // GLYPH_HEAD_RES_OFFSET +}; + +/** + * @brief struct LangBinHeader for font + * refer to ui_font.h + */ +struct LangBinHeader { + char fontVersion[FONT_VERSION_LEN]; // FONT_VERSION_OFFSET + char fontMagic[FONT_MAGIC_NUM_LEN]; // FONT_MAGIC_NUM_OFFSET +}; + +/** + * @brief struct LangFontBinHeader for font + * refer to ui_font.h + */ +struct LangFontBinHeader { + uint32_t offset; // LANG_OFFSET_LEN + uint32_t size; // LANG_SIZE_LEN +}; + +/** + * @brief struct LangTexsTableHeader for font + * refer to ui_font.h + */ +struct LangTexsTableHeader { + uint32_t textParamStart; + uint32_t textParamLen; // LANG_TEXTS_PARAM_LEN + uint32_t textUtf8ParamStart; + uint32_t textUtf8ParamLen; // LANG_TEXTS_UTF8P_LEN + uint32_t textUtf8Start; + uint32_t textUtf8Len; // LANG_TEXTS_UTF8_LEN + uint32_t textCodepointsStart; + uint32_t textCodepointsMaxItemLen; + uint32_t textCodepointsTotalLen; +}; + +/** + * @brief struct LangTexsUtf8Param for font + * refer to ui_font.h + */ +struct LangTexsUtf8Param { + uint32_t offset; + uint32_t len; + uint32_t codePointOffset; + uint32_t codePointLen; +}; + +/** + * @brief struct KernNode for kerning of font + * refer to ui_font.h + */ +struct KernNode { + uint32_t unicode; // GLYPH_UNICODE_LEN + int16_t kernValue; // GLYPH_KERN_SIZE_LEN + uint8_t found; // found the kerning or not +}; + +/** + * @brief struct TtfHeader for header of ttftab.bin + * refer to ui_font.h + */ +struct TtfHeader { + uint8_t ttfId; + uint32_t offset; + uint32_t len; +}; + +struct UITextLanguageFontParam { + uint8_t size; // Invalid value for vector font + uint8_t fontWeight; + uint8_t shaping; + uint8_t ttfId; // auto create during registration for vector font + const char* ttfName; +}; // UITextLanguageFontParam + +struct TextIsoHeader { + uint16_t paramLen; + uint16_t strLen; +}; + +struct TextIsoParam { + uint16_t offset; + uint16_t len; +}; + +struct LangTextParam { + uint8_t fontDirect; // refer to UITextLanguageDirect + uint8_t fontSize; + const char* familyName; // such as "Roboto-Medium" + const char* langName; // such as "ar", "zh" +}; + +struct FileCommonHeader { + const char magicWord[5]; // 5:file identifier's length is 5 + uint32_t fileLength; +}; +#pragma pack() + +/** + * @brief Get the Text Lang Fonts Table + * @param uint8_t langFontId [in] the font id + * @return UITextLanguageFontParam* the font table, definition is in font tool + */ +UITextLanguageFontParam* GetTextLangFontsTable(uint8_t langFontId); + +/** + * @brief Get the Total Lang Id + * @return uint8_t the total Lang id, definition is in font tool + */ +uint8_t GetTotalLangId(); + +/** + * @brief Get the Total Font Id + * @return uint8_t the total font id, definition is in font tool + */ +uint8_t GetTotalFontId(); + +uint8_t GetBitmapFontIdMax(); + +/** + * @brief Get the Total Text Id + * @return uint8_t the total text id, definition is in font tool + */ +uint16_t GetTotalTextId(); + +/** + * @brief Get the Lang Text default param table + * @return LangTextParam* the param table, definition is in font tool + */ +LangTextParam* GetLangTextDefaultParamTable(); +} // namespace OHOS +#endif /* UI_FONT_HEADER_H */ \ No newline at end of file diff --git a/interfaces/kits/layout/flex_layout.h b/interfaces/kits/layout/flex_layout.h new file mode 100755 index 0000000..940c3a4 --- /dev/null +++ b/interfaces/kits/layout/flex_layout.h @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +/** + * @addtogroup UI_Layout + * @{ + * + * @brief Defines UI layouts such as FlexLayout and GridLayout. + * + * @since 1.0 + * @version 1.0 + */ + +/** + * @file flex_layout.h + * + * @brief Declares a flexible layout container. You can perform simple adaptive layout on child views that the + * container holds, for example, to evenly arrange all child views in the same row or column. + * + * @since 1.0 + * @version 1.0 + */ + +#ifndef GRAPHIC_LITE_FLEX_LAYOUT_H +#define GRAPHIC_LITE_FLEX_LAYOUT_H + +#include "layout.h" + +namespace OHOS { +/** + * @brief Defines a flexible layout container. You can perform simple adaptive layout on child views that the + * container holds, for example, to evenly arrange all child views in the same row or column. + * + * @since 1.0 + * @version 1.0 + */ +class FlexLayout : public Layout { +public: + static constexpr uint8_t NOWRAP = 0; + static constexpr uint8_t WRAP = 1; + + /** + * @brief A default constructor used to create a FlexLayout instance. + * @since 1.0 + * @version 1.0 + */ + FlexLayout() + : majorAlign_(ALIGN_START), secondaryAlign_(ALIGN_CENTER), wrap_(NOWRAP), rowCount_(1), columnCount_(1) {} + + /** + * @brief A destructor used to delete the FlexLayout instance. + * @since 1.0 + * @version 1.0 + */ + virtual ~FlexLayout() {} + + /** + * @brief Sets the alignment mode of the primary axis (the axis where the layout direction is located). + * The child views in the layout are placed in this mode in the direction of the primary axis. + * @param align Indicates the alignment mode to set. The value can be ALIGN_START, ALIGN_END, + * ALIGN_CENTER, ALIGN_EVENLY, ALIGN_AROUND, or ALIGN_BETWEEN. + * @since 1.0 + * @version 1.0 + */ + void SetMajorAxisAlign(const AlignType& align) + { + majorAlign_ = align; + } + + /** + * @brief Sets the alignment mode of the secondary axis (the axis perpendicular to the set layout direction). + * @param align Indicates the alignment mode to set. The value can be ALIGN_START, ALIGN_CENTER, + * or ALIGN_END. + * @since 1.0 + * @version 1.0 + */ + void SetSecondaryAxisAlign(const AlignType& align) + { + secondaryAlign_ = align; + } + + /** + * @brief Sets whether to support word wrap. + * @param wrap Indicates the word wrap attribute. + * @since 1.0 + * @version 1.0 + */ + void SetFlexWrap(uint8_t wrap) + { + wrap_ = wrap; + } + + /** + * @brief Lays out all child views according to the preset arrangement mode. + * @param needInvalidate Specifies whether to refresh the invalidated area after the layout is complete. + * Value true means to refresh the invalidated area after the layout is complete, + * and false means the opposite. + * @since 1.0 + * @version 1.0 + */ + virtual void LayoutChildren(bool needInvalidate = false) override; +private: + void LayoutHorizontal(); + void LayoutVertical(); + void CalValidLength(uint16_t& totalValidLength, uint16_t& allChildNum); + void GetStartPos(const int16_t& length, int16_t& pos, int16_t& interval, int16_t count, + uint16_t* validLengths, uint16_t* childsNum); + void GetNoWrapStartPos(const int16_t& length, int16_t& majorPos, int16_t& interval); + void CalRowCount(); + void GetRowMaxHeight(uint16_t size, uint16_t* maxRosHegiht); + void GetRowsWidth(uint16_t rowNum, uint16_t* rowsWidth, uint16_t* rowsChildNum); + void GetRowStartPos(int16_t& pos, int16_t& interval, int16_t count, + uint16_t* rowsWidth, uint16_t* rowsChildNum); + void CalColumnCount(); + void GetColumnMaxWidth(uint16_t size, uint16_t* maxColumnsWidth); + void GetColumnsHeight(uint16_t columnNum, uint16_t* columnsHeight, uint16_t* columnsChildNum); + void GetColumnStartPos(int16_t& pos, int16_t& interval, int16_t count, + uint16_t* columnsHeight, uint16_t* columnsChildNum); + void GetCrossAxisPosY(int16_t& posY, uint16_t& count, uint16_t* rowsMaxHeight, UIView* child); + void GetCrossAxisPosX(int16_t& posX, uint16_t& count, uint16_t* columnsMaxWidth, UIView* child); + static constexpr uint16_t MAX_COUNT_DEFAULT = 100; + AlignType majorAlign_; + AlignType secondaryAlign_; + uint8_t wrap_; + uint16_t rowCount_; + uint16_t columnCount_; +}; +} // namespace OHOS +#endif // GRAPHIC_LITE_FLEX_LAYOUT_H diff --git a/interfaces/kits/layout/grid_layout.h b/interfaces/kits/layout/grid_layout.h new file mode 100755 index 0000000..6dbbb2a --- /dev/null +++ b/interfaces/kits/layout/grid_layout.h @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef GRAPHIC_LITE_GRID_LAYOUT_H +#define GRAPHIC_LITE_GRID_LAYOUT_H + +/** + * @addtogroup UI_Layout + * @{ + * + * @brief Defines UI layouts such as FlexLayout and GridLayout. + * + * @since 1.0 + * @version 1.0 + */ + +/** + * @file grid_layout.h + * + * @brief Declares a grid layout container. You can perform simple grid layout on child views that the container holds. + * + * @since 1.0 + * @version 1.0 + */ + +#include "layout.h" + +namespace OHOS { +/** + * @brief Defines a grid layout container. You can perform simple grid layout on child views that the container holds. + * + * @since 1.0 + * @version 1.0 + */ +class GridLayout : public Layout { +public: + /** + * @brief A default constructor used to create a GridLayout instance. + * @since 1.0 + * @version 1.0 + */ + GridLayout() : rows_(0), cols_(0) {} + + /** + * @brief A destructor used to delete the GridLayout instance. + * @since 1.0 + * @version 1.0 + */ + virtual ~GridLayout() {} + + /** + * @brief Sets the number of rows in a grid. + * @param rows Indicates the number of rows to set. + * @since 1.0 + * @version 1.0 + */ + void SetRows(const uint16_t& rows) + { + rows_ = rows; + } + + /** + * @brief Sets the number of columns in a grid. + * @param cols Indicates the number of columns to set. + * @since 1.0 + * @version 1.0 + */ + void SetCols(const uint16_t& cols) + { + cols_ = cols; + } + + /** + * @brief Lays out all child views according to the preset arrangement mode. + * @param needInvalidate Specifies whether to refresh the invalidated area after the layout is complete. + * Value true means to refresh the invalidated area after the layout is complete, + * and false means the opposite. + * @since 1.0 + * @version 1.0 + */ + virtual void LayoutChildren(bool needInvalidate = false) override; + +private: + void LayoutHorizontal(); + void LayoutVertical(); + + uint16_t rows_; + uint16_t cols_; +}; +} // namespace OHOS +#endif // GRAPHIC_LITE_GRID_LAYOUT_H diff --git a/interfaces/kits/layout/layout.h b/interfaces/kits/layout/layout.h new file mode 100755 index 0000000..f2c0d96 --- /dev/null +++ b/interfaces/kits/layout/layout.h @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +/** + * @addtogroup UI_Layout + * @{ + * + * @brief Defines UI layouts such as FlexLayout and GridLayout. + * + * @since 1.0 + * @version 1.0 + */ + +/** + * @file layout.h + * + * @brief Declares the base class of the layout, which indicates the basic data types and operations that may be + * used in the layout. + * + * @since 1.0 + * @version 1.0 + */ + +#ifndef GRAPHIC_LITE_LAYOUT_H +#define GRAPHIC_LITE_LAYOUT_H + +#include "components/ui_view_group.h" + +namespace OHOS { +using DirectionType = uint8_t; +using AlignType = uint8_t; +/* Arranges child views by row from left to right. */ +const DirectionType LAYOUT_HOR = 0; +/* Arranges child views by row from right to left. */ +const DirectionType LAYOUT_HOR_R = 1; +/* Arranges child views by column from top to bottom. */ +const DirectionType LAYOUT_VER = 2; +/* Arranges child views by column from bottom to top. */ +const DirectionType LAYOUT_VER_R = 3; + +/* Places all child views from the start point to the end point. */ +const AlignType ALIGN_START = 0; +/* Places all child views from the end point to the start point. */ +const AlignType ALIGN_END = 1; +/* Places all child views in the center. */ +const AlignType ALIGN_CENTER = 2; +/* Evenly places all child views between the start point and end point. The distance between the start point and + the end as well as the distance between the end point and the end is the same as that between child views. */ +const AlignType ALIGN_EVENLY = 3; +/* Evenly places all child views between the start point and end point. The distance between the start point and + the end as well as the distance between the end point and the end is half of the distance between child views. */ +const AlignType ALIGN_AROUND = 4; +/* Evenly places all child views between the start point and end point. No left or right margin is reserved. */ +const AlignType ALIGN_BETWEEN = 5; + +/** + * @brief Defines the base class of the layout, which indicates the basic data types and operations that may be used in + * the layout. + * + * @since 1.0 + * @version 1.0 + */ +class Layout : public UIViewGroup { +public: + /** + * @brief A default constructor used to create a Layout instance. + * @since 1.0 + * @version 1.0 + */ + Layout() : direction_(LAYOUT_HOR) {} + + /** + * @brief A destructor used to delete the Layout instance. + * @since 1.0 + * @version 1.0 + */ + virtual ~Layout() {} + + /** + * @brief Sets the layout direction. + * @param direction Indicates the direction of the layout. Available values are as follows: + * LAYOUT_HOR: from left to right + * LAYOUT_HOR_R: from right to left + * LAYOUT_VER: from top to bottom + * LAYOUT_VER_R: from bottom to top + * @since 1.0 + * @version 1.0 + */ + void SetLayoutDirection(const DirectionType& direction) + { + direction_ = direction; + } + +protected: + DirectionType direction_; +}; +} // namespace OHOS +#endif // GRAPHIC_LITE_LAYOUT_H diff --git a/interfaces/kits/layout/list_layout.h b/interfaces/kits/layout/list_layout.h new file mode 100755 index 0000000..ec1e801 --- /dev/null +++ b/interfaces/kits/layout/list_layout.h @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +/** + * @addtogroup UI_Layout + * @{ + * + * @brief Defines UI layouts such as FlexLayout and GridLayout. + * + * @since 1.0 + * @version 1.0 + */ + +#ifndef GRAPHIC_LITE_LIST_LAYOUT_H +#define GRAPHIC_LITE_LIST_LAYOUT_H + +#include "flex_layout.h" + +namespace OHOS { +class ListLayout : public FlexLayout { +public: + /** @brief Default constructor */ + ListLayout(const uint8_t direction = VERTICAL); + + /** + * @brief Destructor + */ + virtual ~ListLayout() {} + + /** + * @brief set list direction, HORIZONTAL list view will recount X position, VERTICAL recount Y. + * + * @param [in] direction the direction, @see HORIZONTAL, VERTICAL. + */ + void SetDirection(uint8_t direction); + + /** + * @brief get list direction. + * + * @param [in] null. + */ + uint8_t GetDirection() + { + return listDirection_; + } + + static constexpr uint8_t HORIZONTAL = 0; + static constexpr uint8_t VERTICAL = 1; + +protected: + void SetLayoutDirect(uint8_t direction); + void OnChildChanged() override; + uint8_t listDirection_; +}; +} // namespace OHOS +#endif // GRAPHIC_LITE_LIST_LAYOUT_H diff --git a/interfaces/kits/themes/theme.h b/interfaces/kits/themes/theme.h new file mode 100755 index 0000000..5c577d4 --- /dev/null +++ b/interfaces/kits/themes/theme.h @@ -0,0 +1,192 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +/** + * @addtogroup UI_Theme + * @{ + * + * @brief Defines UI themes. + * + * @since 1.0 + * @version 1.0 + */ + +/** + * @file theme.h + * + * @brief Declares the base class used to define the functions related to the styles of different components. + * + * @since 1.0 + * @version 1.0 + */ + +#ifndef GRAPHIC_LITE_THEME_H +#define GRAPHIC_LITE_THEME_H + +#include "components/ui_view.h" +#include "style.h" + +namespace OHOS { +/** + * @brief Stores styles of a button in its different states. + */ +struct ButtonStyle { + /** Style when released */ + Style released; + /** Style when pressed */ + Style pressed; + /** Style when inactive */ + Style inactive; +}; + +/** + * @brief Defines the theme class used to define the functions related to the styles of different components. + * + * @since 1.0 + * @version 1.0 + */ +class Theme : public HeapBase { +public: + /** + * @brief A constructor used to create a Theme instance. + * + * @since 1.0 + * @version 1.0 + */ + Theme(); + + /** + * @brief A destructor used to delete the Theme instance. + * + * @since 1.0 + * @version 1.0 + */ + virtual ~Theme(){}; + + /** + * @brief Obtains the basic style. + * + * @return Returns the basic style. + * @since 1.0 + * @version 1.0 + */ + Style& GetMainStyle() + { + return basicStyle_; + } + + /** + * @brief Obtains the style of this button. + * + * @return Returns the button style. + * @since 1.0 + * @version 1.0 + */ + ButtonStyle& GetButtonStyle() + { + return buttonStyle_; + } + + /** + * @brief Obtains the style of this label. + * + * @return Returns the label style. + * @since 1.0 + * @version 1.0 + */ + Style& GetLabelStyle() + { + return labelStyle_; + } + + /** + * @brief Obtains the background style of this picker. + * + * @return Returns the background style of this picker. + * @since 1.0 + * @version 1.0 + */ + Style& GetPickerBackgroundStyle() + { + return pickerBackgroundStyle_; + } + + /** + * @brief Obtains the highlight style of this picker. + * + * @return Returns the highlight style of this picker. + * @since 1.0 + * @version 1.0 + */ + Style& GetPickerHighlightStyle() + { + return pickerHighlightStyle_; + } + + /** + * @brief Obtains the background style of this progress bar. + * + * @return Returns the background style of this progress bar. + * @since 1.0 + * @version 1.0 + */ + Style& GetProgressBackgroundStyle() + { + return progressBackgroundStyle_; + } + + /** + * @brief Obtains the foreground style of this progress bar. + * + * @return Returns the foreground style of this progress bar. + * @since 1.0 + * @version 1.0 + */ + Style& GetProgressForegroundStyle() + { + return progressForegroundStyle_; + } + + /** + * @brief Obtains the style of this slider knob. + * + * @return Returns the style of this slider knob. + * @since 1.0 + * @version 1.0 + */ + Style& GetSliderKnobStyle() + { + return sliderKnobStyle_; + } + +protected: + Style basicStyle_; + ButtonStyle buttonStyle_; + Style labelStyle_; + Style pickerBackgroundStyle_; + Style pickerHighlightStyle_; + Style progressBackgroundStyle_; + Style progressForegroundStyle_; + Style sliderKnobStyle_; + + virtual void InitBasicStyle(); + virtual void InitButtonStyle(); + virtual void InitLabelStyle(); + virtual void InitPickerStyle(); + virtual void InitProgressStyle(); + virtual void InitSliderStyle(); +}; +} // namespace OHOS +#endif // GRAPHIC_LITE_THEME_H diff --git a/interfaces/kits/themes/theme_manager.h b/interfaces/kits/themes/theme_manager.h new file mode 100755 index 0000000..e3c29d4 --- /dev/null +++ b/interfaces/kits/themes/theme_manager.h @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +/** + * @addtogroup UI_Theme + * @{ + * + * @brief Defines UI themes. + * + * @since 1.0 + * @version 1.0 + */ + +/** + * @file theme_manager.h + * + * @brief Declares the singleton class used to manage the current screen theme of an application. + * + * @since 1.0 + * @version 1.0 + */ + +#ifndef GRAPHIC_LITE_THEME_MANAGER_H +#define GRAPHIC_LITE_THEME_MANAGER_H + +#include "themes/theme.h" + +namespace OHOS { +/** + * @brief Declares the singleton class used to manage the current screen theme of an application. + * + * @since 1.0 + * @version 1.0 + */ +class ThemeManager : public HeapBase { +public: + /** + * @brief Obtains the singleton instance of the ThemeManager class. + * + * @return Returns the singleton instance of the ThemeManager class. + */ + static ThemeManager& GetInstance() + { + static ThemeManager instance; + return instance; + } + + /** + * @brief Sets the current screen theme for this application. + * + * @param theme Indicates the theme to set. + * + * @since 1.0 + * @version 1.0 + */ + void SetCurrent(Theme* theme); + + /** + * @brief Obtains the current screen theme of this application. + * + * @return Returns the current theme if available; returns nullptr otherwise. + * + * @since 1.0 + * @version 1.0 + */ + Theme* GetCurrent() + { + return theme_; + }; + +private: + ThemeManager() : theme_(nullptr) {} + ~ThemeManager() {} + + Theme* theme_; +}; +} // namespace OHOS +#endif // GRAPHIC_LITE_THEME_MANAGER_H diff --git a/interfaces/kits/window/window.h b/interfaces/kits/window/window.h new file mode 100755 index 0000000..f67e92b --- /dev/null +++ b/interfaces/kits/window/window.h @@ -0,0 +1,226 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +/** + * @addtogroup Window + * @{ + * + * @brief Provides window management capabilities, including creating, destroying, showing, hiding, moving, + * resizing a window, raising a window to the top, and lowering a window to the bottom. + * + * @since 1.0 + * @version 1.0 + */ + +/** + * @file window.h + * + * @brief Declares the Window class that provides a drawing canvas for the RootView, + * which represents the root node of a view tree. + * + * Each window is bound to a RootView. For details, see {@link RootView}. + * The Window class also provides window management capabilities, including creating, destroying, showing, + * hiding, moving, resizing a window, raising a window to the top, and lowering a window to the bottom. + * + * @since 1.0 + * @version 1.0 + */ + +#ifndef GRAPHIC_LITE_WINDOW_H +#define GRAPHIC_LITE_WINDOW_H + +#include "color.h" +#include "components/root_view.h" + +namespace OHOS { +/** + * @brief Enumerates the pixel formats of this window. + * + * @since 1.0 + * @version 1.0 + */ +enum WindowPixelFormat { + /** RGB565 format */ + WINDOW_PIXEL_FORMAT_RGB565 = 101, + /** ARGB1555 format */ + WINDOW_PIXEL_FORMAT_ARGB1555, + /** RGB888 format */ + WINDOW_PIXEL_FORMAT_RGB888, + /** ARGB8888 format */ + WINDOW_PIXEL_FORMAT_ARGB8888, +}; + +/** + * @brief Sets the attributes for this window. + * + * This structure stores the attributes such as the rectangle, opacity, and pixel format of this window. + * + * @since 1.0 + * @version 1.0 + */ +struct WindowConfig { + WindowConfig() : rect(), + opacity(OPA_OPAQUE), + pixelFormat(WINDOW_PIXEL_FORMAT_ARGB8888), + compositeMode(COPY), + isModal(false) + { + } + ~WindowConfig() {} + enum CompositeMode { + COPY, + BLEND + }; + /** Rectangle */ + Rect rect; + /** Opacity, within [0, 255] */ + uint8_t opacity; + /** Pixel format */ + WindowPixelFormat pixelFormat; + CompositeMode compositeMode; + bool isModal; +}; + +/** + * @brief Provides a drawing canvas for the RootView, which represents the root node of a view tree. + * + * Each window is bound to a RootView. For details, see {@link RootView}. + * This class also provides window management capabilities, including creating, destroying, showing, hiding, + * moving, resizing a window, raising a window to the top, and lowering a window to the bottom. + * + * @since 1.0 + * @version 1.0 + */ +class Window { +public: + /** + * @brief Creates a Window instance. + * + * @param config Indicates the window configuration. For details, see {@link WindowConfig}. + * @return Returns the Window instance if the operation is successful; returns nullptr otherwise. + * @since 1.0 + * @version 1.0 + */ + static Window* CreateWindow(const WindowConfig& config); + + /** + * @brief Destroys a specified window. + * + * @param window Indicates the Window instance to destroy. + * @since 1.0 + * @version 1.0 + */ + static void DestoryWindow(Window* window); + + /** + * @brief Binds the RootView to this window. + * + * @param rootView Indicates the RootView to bind. + * @since 1.0 + * @version 1.0 + */ + virtual void BindRootView(RootView* rootView) = 0; + + /** + * @brief Unbinds the RootView from this window. + * + * @since 1.0 + * @version 1.0 + */ + virtual void UnbindRootView() = 0; + + /** + * @brief Obtains the RootView bound to this window. + * + * @return Returns the RootView if available; returns nullptr otherwise. + * @since 1.0 + * @version 1.0 + */ + virtual RootView* GetRootView() = 0; + + /** + * @brief Obtains the rectangle information (position, width, and height) of this window. + * + * @return Returns the rectangle information of this window. + * @since 1.0 + * @version 1.0 + */ + virtual Rect GetRect() = 0; + + /** + * @brief Shows this window. + * + * @since 1.0 + * @version 1.0 */ + virtual void Show() = 0; + + /** + * @brief Hides this window. + * + * @since 1.0 + * @version 1.0 + */ + virtual void Hide() = 0; + + /** + * @brief Moves this window to a specified position. + * + * @param x Indicates the x-coordinate of the target position. + * @param y Indicates the y-coordinate of the target position. + * @since 1.0 + * @version 1.0 + */ + virtual void MoveTo(int16_t x, int16_t y) = 0; + + /** + * @brief Resizes this window. + * + * @param width Indicates the new window width. + * @param height Indicates the new window height. + * @since 1.0 + * @version 1.0 + */ + virtual void Resize(int16_t width, int16_t height) = 0; + + /** + * @brief Raises this window to the top. + * + * @since 1.0 + * @version 1.0 + */ + virtual void RaiseToTop() = 0; + + /** + * @brief Lowers this window to the bottom. + * + * @since 1.0 + * @version 1.0 + */ + virtual void LowerToBottom() = 0; + + /** + * @brief Obtains the unique ID of this window. + * + * The window ID is within [0, 31]. An ID will be reused after the current window is destroyed. + * A maximum of 32 windows can be displayed at the same time. + * + * @return Returns the unique ID of this window if the operation is successful; returns -1 otherwise. + * @since 1.0 + * @version 1.0 + */ + virtual int32_t GetWindowId() = 0; +}; +} +#endif \ No newline at end of file diff --git a/test/framework/BUILD.gn b/test/framework/BUILD.gn new file mode 100755 index 0000000..9dd08db --- /dev/null +++ b/test/framework/BUILD.gn @@ -0,0 +1,84 @@ +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. +# 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. + +import("//build/lite/config/component/lite_component.gni") +import("//build/lite/config/subsystem/graphic/config.gni") + +static_library("framework") { + sources = [ + "../uitest/test_animator/ui_test_animator.cpp", + "../uitest/test_anti_aliasing/ui_test_anti_aliasing.cpp", + "../uitest/test_arc_label/ui_test_arc_label.cpp", + "../uitest/test_button/ui_test_button.cpp", + "../uitest/test_canvas/ui_test_canvas.cpp", + "../uitest/test_chart/ui_test_chart_pillar.cpp", + "../uitest/test_chart/ui_test_chart_polyline.cpp", + "../uitest/test_dialog/ui_test_dialog.cpp", + "../uitest/test_digital_clock/ui_test_digital_clock.cpp", + "../uitest/test_draw_line/ui_test_draw_line.cpp", + "../uitest/test_draw_rect/ui_test_draw_rect.cpp", + "../uitest/test_event_injector/ui_test_event_injector.cpp", + "../uitest/test_font/ui_test_font.cpp", + "../uitest/test_image/ui_test_image.cpp", + "../uitest/test_image_animator/ui_test_image_animator.cpp", + "../uitest/test_input_event/ui_test_input_event.cpp", + "../uitest/test_label/ui_test_label.cpp", + "../uitest/test_layout/ui_test_advanced_layout.cpp", + "../uitest/test_layout/ui_test_basic_layout.cpp", + "../uitest/test_opacity/ui_test_opacity.cpp", + "../uitest/test_picker/ui_test_ui_picker.cpp", + "../uitest/test_progress_bar/ui_test_box_progress.cpp", + "../uitest/test_progress_bar/ui_test_circle_progress.cpp", + "../uitest/test_qrcode/ui_test_qrcode.cpp", + "../uitest/test_render/ui_test_render.cpp", + "../uitest/test_rotate_input/ui_test_rotate_input.cpp", + "../uitest/test_screenshot/ui_test_screenshot.cpp", + "../uitest/test_slider/ui_test_slider.cpp", + "../uitest/test_texture_mapper/ui_test_texture_mapper.cpp", + "../uitest/test_transform/ui_test_transform.cpp", + "../uitest/test_ui_analog_clock/ui_test_analog_clock.cpp", + "../uitest/test_ui_dump_dom_tree/ui_test_dump_dom.cpp", + "../uitest/test_ui_list/ui_test_ui_list.cpp", + "../uitest/test_ui_list_view/ui_test_list_layout.cpp", + "../uitest/test_ui_scroll_view/ui_test_ui_scroll_view.cpp", + "../uitest/test_ui_swipe_view/ui_test_ui_swipe_view.cpp", + "../uitest/test_vector_font/ui_test_vector_font.cpp", + "../uitest/test_video/ui_test_video.cpp", + "../uitest/test_view_percent/ui_test_view_percent.cpp", + "../uitest/test_view_scale_rotate/ui_test_view_scale_rotate.cpp", + "src/test_ability.cpp", + "src/test_case_list_adapter.cpp", + "src/ui_test_app.cpp", + "src/ui_test_group.cpp", + ] + include_dirs = [ + "include", + "../uitest", + "../../tools", + "../../interfaces", + "../../frameworks", + "//foundation/multimedia/utils/lite/include", + "//foundation/multimedia/media_lite/interfaces/kits/player_lite", + ] + public_deps = [ + "//build/lite/config/component/cJSON:cjson_shared", + "//foundation/graphic/ui:ui", + "//foundation/graphic/wms:wms_client", + ] + configs += [ "//foundation/graphic/ui:graphic_define_config" ] +} + +group("lite_graphic_test_framework") { + public_deps = [] + if (ohos_build_type == "debug") { + public_deps += [ ":framework" ] + } +} diff --git a/test/framework/include/test_case_list_adapter.h b/test/framework/include/test_case_list_adapter.h new file mode 100755 index 0000000..bf65b35 --- /dev/null +++ b/test/framework/include/test_case_list_adapter.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef TEST_CASE_LIST_ADAPTER_H +#define TEST_CASE_LIST_ADAPTER_H + +#include "components/abstract_adapter.h" +#include "components/root_view.h" +#include "components/ui_label.h" +#include "components/ui_label_button.h" + +namespace OHOS { +class TestCaseListAdapter : public AbstractAdapter { +public: + TestCaseListAdapter(RootView* rootView, UIView* mainList, UILabelButton* backBtn, + UILabel* label, UILabel* testTitleLabel) + : rootView_(rootView), mainList_(mainList), backBtn_(backBtn), testCaseLabel_(label), + testLabel_(testTitleLabel) {} + ~TestCaseListAdapter() {} + UIView* GetView(UIView* inView, int16_t index) override; + uint16_t GetCount() override; + +private: + RootView* rootView_; + UIView* mainList_; + UILabelButton* backBtn_; + UILabel* testCaseLabel_; + UILabel* testLabel_; +}; +} // namespace OHOS +#endif // TEST_CASE_LIST_ADAPTER_H \ No newline at end of file diff --git a/test/framework/include/test_resource_config.h b/test/framework/include/test_resource_config.h new file mode 100755 index 0000000..aa61caa --- /dev/null +++ b/test/framework/include/test_resource_config.h @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef TEST_RESOURCE_CONFIG_H +#define TEST_RESOURCE_CONFIG_H + +#include "graphic_config.h" + +namespace OHOS { +#if defined QT_COMPILER +#define IMAGE_DIR "..\\simulator\\config\\images\\" +#define FACE_DIR "..\\simulator\\config\\faces\\default\\" +#elif defined _WIN32 +#define IMAGE_DIR "..\\config\\images\\" +#define FACE_DIR "..\\config\\faces\\default\\" +#else +#define IMAGE_DIR RESOURCE_DIR +#define FACE_DIR RESOURCE_DIR +#endif + +#define BLUE_RGB888_IMAGE_PATH (IMAGE_DIR "blue_rgb888.bin") +#define BLUE_ARGB8888_IMAGE_PATH (IMAGE_DIR "blue_argb8888.bin") +#define BLUE_RGB565_IMAGE_PATH (IMAGE_DIR "blue_rgb565.bin") +#define BLUE_IMAGE_PATH (IMAGE_DIR "blue.png") +#define RED_IMAGE_PATH (IMAGE_DIR "red.png") +#define GREEN_IMAGE_PATH (IMAGE_DIR "green.png") +#define YELLOW_IMAGE_PATH (IMAGE_DIR "yellow.png") +#define IMAGE_ANIMATOR_0_PATH (IMAGE_DIR "image_animator_0.bin") +#define IMAGE_ANIMATOR_1_PATH (IMAGE_DIR "image_animator_1.bin") +#define IMAGE_ANIMATOR_2_PATH (IMAGE_DIR "image_animator_2.bin") +#define IMAGE_ANIMATOR_3_PATH (IMAGE_DIR "image_animator_3.bin") +#define B024_002_IMAGE_PATH (FACE_DIR "B024_002.bin") +#define B024_009_IMAGE_PATH (FACE_DIR "B024_009.bin") +#define B024_010_IMAGE_PATH (FACE_DIR "B024_010.bin") +#define B024_011_IMAGE_PATH (FACE_DIR "B024_011.bin") +#define SLIDER_BACKGROUND_IMAGE_PATH (IMAGE_DIR "sliderBackground.bin") +#define SLIDER_INDICATOR_IMAGE_PATH (IMAGE_DIR "sliderIndicator.bin") +#define SLIDER_KNOB_IMAGE_PATH (IMAGE_DIR "sliderKnob.bin") +#define JPEG_IMAGE_PATH (IMAGE_DIR "jpeg.jpg") +#define PNG_1_PALETTE_IMAGE_PATH (IMAGE_DIR "png_1_palette.png") +#define PNG_2_PALETTE_IMAGE_PATH (IMAGE_DIR "png_2_palette.png") +#define PNG_4_PALETTE_IMAGE_PATH (IMAGE_DIR "png_4_palette.png") +#define PNG_8_PALETTE_IMAGE_PATH (IMAGE_DIR "png_8_palette.png") +#define PNG_8_GRAY_IMAGE_PATH (IMAGE_DIR "png_8_gray.png") +#define PNG_16_GRAY_IMAGE_PATH (IMAGE_DIR "png_16_gray.png") +#define PNG_24_RGB_IMAGE_PATH (IMAGE_DIR "png_24_rgb.png") +#define PNG_32_RGB_ALPHA_IMAGE_PATH (IMAGE_DIR "png_32_rgba.png") +#ifndef VERSION_LITE +#define GIF_IMAGE_PATH1 (IMAGE_DIR "gif_image1.gif") +#define GIF_IMAGE_PATH2 (IMAGE_DIR "gif_image2.gif") +#define GIF_IMAGE_PATH_ERROR (IMAGE_DIR "gif_error.gif") +#define TIF_IMAGE_PATH (IMAGE_DIR "tif_image.tif") +#endif +#define VIDEO_SOURCE_DIRECTORY (IMAGE_DIR "video.mp4") +#define TEST_RIGHT_ARROW (IMAGE_DIR "ic_arrow_right.png") +#define TEST_BACK_LEFT_ARROW (IMAGE_DIR "ic_back.png") +} // namespace OHOS +#endif // TEST_RESOURCE_CONFIG_H \ No newline at end of file diff --git a/test/framework/include/ui_test.h b/test/framework/include/ui_test.h new file mode 100755 index 0000000..03993e3 --- /dev/null +++ b/test/framework/include/ui_test.h @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef UI_TEST_H +#define UI_TEST_H + +#include "components/ui_label.h" +#include "components/ui_view_group.h" +#include "common/screen.h" + +namespace OHOS { +static constexpr uint16_t TITLE_LABEL_DEFAULT_HEIGHT = 29; +static constexpr uint16_t FONT_DEFAULT_SIZE = 20; +static constexpr uint16_t VIEW_DISTANCE_TO_LEFT_SIDE = 48; +static constexpr uint16_t VIEW_DISTANCE_TO_TOP_SIDE = 48; +static constexpr uint16_t VIEW_DISTANCE_TO_LEFT_SIDE2 = 24; +static constexpr uint16_t TEXT_DISTANCE_TO_LEFT_SIDE = 48; +static constexpr uint16_t TEXT_DISTANCE_TO_TOP_SIDE = 11; +static constexpr uint16_t HALF_OPA_OPAQUE = OPA_OPAQUE / 2; +static constexpr uint16_t VIEW_STYLE_BORDER_WIDTH = 2; +static constexpr uint16_t VIEW_STYLE_BORDER_RADIUS = 8; +static constexpr uint16_t BUTTON_LABEL_SIZE = 16; +static constexpr uint8_t BUTTON_STYLE_BORDER_RADIUS_VALUE = 20; +static constexpr uint32_t BUTTON_STYLE_BACKGROUND_COLOR_VALUE = 0xFF333333; +static constexpr uint32_t BUTTON_STYLE_BACKGROUND_COLOR_PRESS = 0xFF2D2D2D; +static constexpr int16_t BACK_BUTTON_HEIGHT = 64; +static constexpr uint16_t BUTTON_WIDHT1 = 80; +static constexpr uint16_t BUTTON_HEIGHT1 = 40; +static constexpr uint16_t BUTTON_WIDHT2 = 120; +static constexpr uint16_t BUTTON_HEIGHT2 = 40; +static constexpr uint16_t BUTTON_WIDHT3 = 150; +static constexpr uint16_t BUTTON_HEIGHT3 = 40; + +class UITest : public HeapBase { +public: + UITest() {} + + virtual ~UITest() {} + + /** + * @brief Set up display enviroment. + * + */ + virtual void SetUp() = 0; + + /** + * @brief Tear down display enviroment. + * + */ + virtual void TearDown() = 0; + + /** + * @brief Get test view to add to root view. + * + * @returns test container view. + * + */ + virtual const UIView* GetTestView() = 0; + + void DeleteChildren(UIView* view) + { + if (view == nullptr) { + return; + } + while (view != nullptr) { + UIView* tempView = view; + view = view->GetNextSibling(); + if (tempView->IsViewGroup() && (tempView->GetViewType() != UI_DIGITAL_CLOCK)) { + DeleteChildren(static_cast(tempView)->GetChildrenHead()); + } + if (tempView->GetParent()) { + static_cast(tempView->GetParent())->Remove(tempView); + } + delete tempView; + } + } + + UILabel* GetTitleLabel(const char* titleName) + { + if (titleName == nullptr) { + return nullptr; + } + UILabel* label = new UILabel(); + if (label == nullptr) { + return nullptr; + } + // 2: half of screen width + label->SetPosition(0, 0, Screen::GetInstance().GetWidth() / 2, TITLE_LABEL_DEFAULT_HEIGHT); + label->SetText(titleName); + label->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); + return label; + } + +protected: + int16_t positionX_ = 0; + int16_t positionY_ = 0; +}; +} // namespace OHOS +#endif \ No newline at end of file diff --git a/test/framework/include/ui_test_app.h b/test/framework/include/ui_test_app.h new file mode 100755 index 0000000..164b452 --- /dev/null +++ b/test/framework/include/ui_test_app.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef UI_TEST_APP_LIST_H +#define UI_TEST_APP_LIST_H + +#include "components/root_view.h" +#include "components/ui_label.h" +#include "components/ui_label_button.h" +#include "components/ui_list.h" +#include "test_case_list_adapter.h" + +namespace OHOS { +class UITestApp { +public: + static UITestApp* GetInstance() + { + static UITestApp instance; + return &instance; + } + void Start(); + void Init(); + +private: + UITestApp() {} + ~UITestApp(); + + UITestApp(const UITestApp&) = delete; + UITestApp& operator=(const UITestApp&) = delete; + UITestApp(UITestApp&&) = delete; + UITestApp& operator=(UITestApp&&) = delete; + + RootView* rootView_ = nullptr; + UIList* mainList_ = nullptr; + TestCaseListAdapter* adapter_ = nullptr; + UILabelButton* backBtn_ = nullptr; + UILabel* testCaseLabel_ = nullptr; + UILabel* testLabel_ = nullptr; +}; +} // namespace OHOS +#endif \ No newline at end of file diff --git a/test/framework/include/ui_test_group.h b/test/framework/include/ui_test_group.h new file mode 100755 index 0000000..e5f7fa7 --- /dev/null +++ b/test/framework/include/ui_test_group.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef UI_TEST_GROUP_H +#define UI_TEST_GROUP_H + +#include "components/ui_view.h" +#include "list.h" + +namespace OHOS { +class UITest; +struct TestCaseInfo { + const char* sliceId; + UITest* testObj; +}; + +class UITestGroup { +public: + static void SetUpTestCase(); + static List& GetTestCase(); + UITest* GetTestCase(const char* id); + static void TearDownTestCase(); + static void AddTestCase(TestCaseInfo testCaseInfo); + +private: + static List testCaseList_; +}; +} // namespace OHOS +#endif \ No newline at end of file diff --git a/test/framework/src/test_ability.cpp b/test/framework/src/test_ability.cpp new file mode 100755 index 0000000..066e56b --- /dev/null +++ b/test/framework/src/test_ability.cpp @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "ui_test_app.h" + +void RunApp() +{ + OHOS::UITestApp::GetInstance()->Start(); +} \ No newline at end of file diff --git a/test/framework/src/test_case_list_adapter.cpp b/test/framework/src/test_case_list_adapter.cpp new file mode 100755 index 0000000..2747d85 --- /dev/null +++ b/test/framework/src/test_case_list_adapter.cpp @@ -0,0 +1,197 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "test_case_list_adapter.h" +#include "common/screen.h" +#include "components/ui_button.h" +#include "components/ui_label_button.h" +#include "list.h" +#include "test_resource_config.h" +#include "ui_test.h" +#include "ui_test_group.h" + +namespace OHOS { +namespace { +const uint16_t TESTCASE_BUTTON_HEIGHT = 64; +const uint16_t STYLE_BORDER_WIDTH_VALUE = 4; +const uint16_t STYLE_BORDER_RADIUS_VALUE = 12; +const char* g_uiTestId = "graphic_ui_test_case_id"; +} // namespace + +uint16_t TestCaseListAdapter::GetCount() +{ + return UITestGroup::GetTestCase().Size(); +} + +class BtnOnClickBackListener : public UIView::OnClickListener { +public: + BtnOnClickBackListener(UIViewGroup* uiView, + UIView* mainList, + UITest* uiTest, + UILabel* testCaseLabel, + UILabel* testLabel) + : rootView_(uiView), mainList_(mainList), uiTest_(uiTest), testCaseLabel_(testCaseLabel), testLabel_(testLabel) + { + } + + ~BtnOnClickBackListener() {} + + bool OnClick(UIView& view, const ClickEvent& event) override + { + if ((rootView_ == nullptr) || (mainList_ == nullptr) || (uiTest_ == nullptr) || (testCaseLabel_ == nullptr) || + (testLabel_ == nullptr)) { + return false; + } + + rootView_->Remove(testCaseLabel_); + rootView_->Remove(&view); + + UIView* tempView = rootView_->GetChildById(g_uiTestId); + if (tempView != nullptr) { + rootView_->Remove(tempView); + uiTest_->TearDown(); + } + + rootView_->Add(testLabel_); + rootView_->Add(mainList_); + rootView_->Invalidate(); + return true; + } + +private: + UIViewGroup* rootView_; + UIView* mainList_; + UILabel* testCaseLabel_; + UILabel* testLabel_; + UITest* uiTest_; +}; + +class BtnOnClickUiTestListener : public UIView::OnClickListener { +public: + BtnOnClickUiTestListener(UIViewGroup* uiView, + UIView* mainList, + UILabelButton* backBtn, + TestCaseInfo* uiTestInfo, + UILabel* testCaseLabel, + UILabel* testLabel) + : rootView_(uiView), + mainList_(mainList), + backBtn_(backBtn), + testCaseLabel_(testCaseLabel), + testLabel_(testLabel), + uiTest_(nullptr), + sliceId_(nullptr) + { + if (uiTestInfo != nullptr) { + uiTest_ = uiTestInfo->testObj; + sliceId_ = uiTestInfo->sliceId; + } + } + ~BtnOnClickUiTestListener() {} + bool OnClick(UIView& view, const ClickEvent& event) override + { + if ((rootView_ == nullptr) || (mainList_ == nullptr) || (backBtn_ == nullptr) || (testCaseLabel_ == nullptr) || + (testLabel_ == nullptr) || (uiTest_ == nullptr) || (sliceId_ == nullptr)) { + return false; + } + rootView_->Remove(testLabel_); + rootView_->Remove(mainList_); + + UIView::OnClickListener* click = backBtn_->GetOnClickListener(); + if (click != nullptr) { + delete click; + click = nullptr; + } + click = new BtnOnClickBackListener(rootView_, mainList_, uiTest_, testCaseLabel_, testLabel_); + backBtn_->SetOnClickListener(click); + rootView_->Add(backBtn_); + if (testCaseLabel_ != nullptr) { + testCaseLabel_->SetText(sliceId_); + } + rootView_->Add(testCaseLabel_); + + uiTest_->SetUp(); + UIView* tempView = const_cast(uiTest_->GetTestView()); + if (tempView != nullptr) { + tempView->SetViewId(g_uiTestId); + tempView->SetPosition(tempView->GetX(), tempView->GetY() + backBtn_->GetHeight()); + rootView_->Add(tempView); + } + rootView_->Invalidate(); + return true; + } + +private: + UIViewGroup* rootView_; + UIView* mainList_; + UILabel* testLabel_; + UILabelButton* backBtn_; + UITest* uiTest_; + UILabel* testCaseLabel_; + const char* sliceId_; +}; + +UIView* TestCaseListAdapter::GetView(UIView* inView, int16_t index) +{ + List testCaseList = UITestGroup::GetTestCase(); + if (testCaseList.IsEmpty()) { + return nullptr; + } + if ((index > testCaseList.Size() - 1) || (index < 0)) { + return nullptr; + } + UILabelButton* item = nullptr; + if (inView == nullptr) { + item = new UILabelButton(); + item->SetPosition(0, 0); + item->SetStyleForState(STYLE_BORDER_WIDTH, STYLE_BORDER_WIDTH_VALUE, UIButton::RELEASED); + item->SetStyleForState(STYLE_BORDER_WIDTH, STYLE_BORDER_WIDTH_VALUE, UIButton::PRESSED); + item->SetStyleForState(STYLE_BORDER_WIDTH, STYLE_BORDER_WIDTH_VALUE, UIButton::INACTIVE); + item->SetStyleForState(STYLE_BORDER_OPA, 0, UIButton::RELEASED); + item->SetStyleForState(STYLE_BORDER_OPA, 0, UIButton::PRESSED); + item->SetStyleForState(STYLE_BORDER_OPA, 0, UIButton::INACTIVE); + item->Resize(Screen::GetInstance().GetWidth() - TEXT_DISTANCE_TO_LEFT_SIDE, TESTCASE_BUTTON_HEIGHT); + } else { + item = static_cast(inView); + } + + UIView::OnClickListener* listener = item->GetOnClickListener(); + if (listener != nullptr) { + delete listener; + listener = nullptr; + } + ListNode* node = testCaseList.Begin(); + for (uint16_t i = 0; i < index; i++) { + node = node->next_; + } + listener = new BtnOnClickUiTestListener(rootView_, mainList_, backBtn_, &node->data_, testCaseLabel_, testLabel_); + item->SetOnClickListener(listener); + item->SetText(node->data_.sliceId); + item->SetFont(DEFAULT_VECTOR_FONT_FILENAME, 24); // 24: means font size + item->SetViewIndex(index); + item->SetAlign(TEXT_ALIGNMENT_LEFT); + item->SetLablePosition(24, 0); // 24: lable x-coordinate + item->SetImageSrc(TEST_RIGHT_ARROW, TEST_RIGHT_ARROW); + // 2: half of button height; 18: half px of image height + item->SetImagePosition(item->GetWidth() - TEXT_DISTANCE_TO_LEFT_SIDE, TESTCASE_BUTTON_HEIGHT / 2 - 18); + item->SetStyleForState(STYLE_BORDER_RADIUS, STYLE_BORDER_RADIUS_VALUE, UIButton::RELEASED); + item->SetStyleForState(STYLE_BORDER_RADIUS, STYLE_BORDER_RADIUS_VALUE, UIButton::PRESSED); + item->SetStyleForState(STYLE_BORDER_RADIUS, STYLE_BORDER_RADIUS_VALUE, UIButton::INACTIVE); + item->SetStyleForState(STYLE_BACKGROUND_COLOR, BUTTON_STYLE_BACKGROUND_COLOR_VALUE, UIButton::RELEASED); + item->SetStyleForState(STYLE_BACKGROUND_COLOR, BUTTON_STYLE_BACKGROUND_COLOR_VALUE, UIButton::PRESSED); + item->SetStyleForState(STYLE_BACKGROUND_COLOR, BUTTON_STYLE_BACKGROUND_COLOR_VALUE, UIButton::INACTIVE); + return item; +} +} // namespace OHOS \ No newline at end of file diff --git a/test/framework/src/ui_test_app.cpp b/test/framework/src/ui_test_app.cpp new file mode 100755 index 0000000..5444a84 --- /dev/null +++ b/test/framework/src/ui_test_app.cpp @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "ui_test_app.h" +#include "common/screen.h" +#include "test_resource_config.h" +#include "ui_test.h" +#include "ui_test_group.h" + +namespace OHOS { +void UITestApp::Start() +{ + if (rootView_ == nullptr) { + rootView_ = RootView::GetInstance(); + rootView_->SetPosition(0, 0); + rootView_->Resize(Screen::GetInstance().GetWidth(), Screen::GetInstance().GetHeight()); + } + Init(); +} + +void UITestApp::Init() +{ + if (backBtn_ == nullptr) { + backBtn_ = new UILabelButton(); + backBtn_->SetPosition(0, 0); + backBtn_->Resize(163, 64); // 163: button width; 64: button height + backBtn_->SetText("Back"); + backBtn_->SetLablePosition(72, 0); // 72: button label x-coordinate + backBtn_->SetFont(DEFAULT_VECTOR_FONT_FILENAME, 24); // 24: means font size + backBtn_->SetImageSrc(TEST_BACK_LEFT_ARROW, TEST_BACK_LEFT_ARROW); + // 27: button Image x-coordinate; 18: half px of image height + backBtn_->SetImagePosition(27, BACK_BUTTON_HEIGHT / 2 - 18); + backBtn_->SetStyleForState(STYLE_BORDER_RADIUS, 0, UIButton::RELEASED); + backBtn_->SetStyleForState(STYLE_BORDER_RADIUS, 0, UIButton::PRESSED); + backBtn_->SetStyleForState(STYLE_BORDER_RADIUS, 0, UIButton::INACTIVE); + backBtn_->SetStyleForState(STYLE_BACKGROUND_OPA, 0, UIButton::RELEASED); + backBtn_->SetStyleForState(STYLE_BACKGROUND_OPA, 0, UIButton::PRESSED); + backBtn_->SetStyleForState(STYLE_BACKGROUND_OPA, 0, UIButton::INACTIVE); + } + if (testCaseLabel_ == nullptr) { + testCaseLabel_ = new UILabel(); + testCaseLabel_->Resize(Screen::GetInstance().GetWidth(), BACK_BUTTON_HEIGHT); + testCaseLabel_->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); + testCaseLabel_->SetText("Test Case Name"); + testCaseLabel_->SetFont(DEFAULT_VECTOR_FONT_FILENAME, 32); // 32: means font size + } + if (testLabel_ == nullptr) { + testLabel_ = new UILabel(); + testLabel_->Resize(Screen::GetInstance().GetWidth(), BACK_BUTTON_HEIGHT); + testLabel_->SetAlign(TEXT_ALIGNMENT_LEFT, TEXT_ALIGNMENT_CENTER); + testLabel_->SetPosition(TEXT_DISTANCE_TO_LEFT_SIDE, 0); + testLabel_->SetText("Test Demo"); + testLabel_->SetFont(DEFAULT_VECTOR_FONT_FILENAME, 32); // 32: means font size + rootView_->Add(testLabel_); + } + if ((mainList_ == nullptr) && (adapter_ == nullptr)) { + uint8_t deltaHeight = 60; // 60: UIList height(64) - first button border width(4) + mainList_ = new UIList(UIList::VERTICAL); + mainList_->SetPosition(24, deltaHeight); // 24: x-coordinate + mainList_->Resize(Screen::GetInstance().GetWidth(), Screen::GetInstance().GetHeight() - deltaHeight); + mainList_->SetThrowDrag(true); + adapter_ = new TestCaseListAdapter(rootView_, mainList_, backBtn_, testCaseLabel_, testLabel_); + UITestGroup::SetUpTestCase(); + mainList_->SetAdapter(adapter_); + rootView_->Add(mainList_); + rootView_->Invalidate(); + } +} + +UITestApp::~UITestApp() +{ + if (mainList_ != nullptr) { + delete adapter_; + adapter_ = nullptr; + } + if (adapter_ != nullptr) { + delete mainList_; + mainList_ = nullptr; + } + if (backBtn_ != nullptr) { + delete backBtn_; + backBtn_ = nullptr; + } + if (rootView_ != nullptr) { + rootView_ = nullptr; + } +} +} // namespace OHOS \ No newline at end of file diff --git a/test/framework/src/ui_test_group.cpp b/test/framework/src/ui_test_group.cpp new file mode 100755 index 0000000..1f7bb78 --- /dev/null +++ b/test/framework/src/ui_test_group.cpp @@ -0,0 +1,164 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "ui_test_group.h" +#include "graphic_config.h" +#include "test_animator/ui_test_animator.h" +#include "test_anti_aliasing/ui_test_anti_aliasing.h" +#include "test_arc_label/ui_test_arc_label.h" +#include "test_button/ui_test_button.h" +#include "test_canvas/ui_test_canvas.h" +#include "test_chart/ui_test_chart_pillar.h" +#include "test_chart/ui_test_chart_polyline.h" +#ifdef ENABLE_WINDOW +#include "test_dialog/ui_test_dialog.h" +#endif +#include "test_draw_line/ui_test_draw_line.h" +#include "test_draw_rect/ui_test_draw_rect.h" +#include "test_event_injector/ui_test_event_injector.h" +#include "test_font/ui_test_font.h" +#include "test_image/ui_test_image.h" +#include "test_image_animator/ui_test_image_animator.h" +#include "test_input_event/ui_test_input_event.h" +#include "test_label/ui_test_label.h" +#include "test_layout/ui_test_advanced_layout.h" +#include "test_layout/ui_test_basic_layout.h" +#include "test_opacity/ui_test_opacity.h" +#include "test_picker/ui_test_ui_picker.h" +#include "test_progress_bar/ui_test_box_progress.h" +#include "test_progress_bar/ui_test_circle_progress.h" +#include "test_qrcode/ui_test_qrcode.h" +#include "test_render/ui_test_render.h" +#if ENABLE_ROTATE_INPUT +#include "test_rotate_input/ui_test_rotate_input.h" +#endif +#ifdef VERSION_STANDARD +#include "test_screenshot/ui_test_screenshot.h" +#endif +#include "test_digital_clock/ui_test_digital_clock.h" +#include "test_slider/ui_test_slider.h" +#include "test_texture_mapper/ui_test_texture_mapper.h" +#include "test_transform/ui_test_transform.h" +#include "test_ui_analog_clock/ui_test_analog_clock.h" +#include "test_ui_dump_dom_tree/ui_test_dump_dom.h" +#include "test_ui_list/ui_test_ui_list.h" +#include "test_ui_list_view/ui_test_list_layout.h" +#include "test_ui_scroll_view/ui_test_ui_scroll_view.h" +#include "test_ui_swipe_view/ui_test_ui_swipe_view.h" +#include "test_view_percent/ui_test_view_percent.h" +#include "test_view_scale_rotate/ui_test_view_scale_rotate.h" +#if ENABLE_VECTOR_FONT +#include "test_vector_font/ui_test_vector_font.h" +#endif +#ifndef VERSION_LITE +#include "test_video/ui_test_video.h" +#endif + +namespace OHOS { +List UITestGroup::testCaseList_; + +void UITestGroup::AddTestCase(TestCaseInfo testCaseInfo) +{ + testCaseList_.PushBack(testCaseInfo); +} + +void UITestGroup::SetUpTestCase() +{ +#if ENABLE_ROTATE_INPUT + testCaseList_.PushBack(TestCaseInfo{"Rotate_Input", new UITestRotateInput()}); +#endif + testCaseList_.PushBack(TestCaseInfo{"View_Scale_Rotate", new UITestViewScaleRotate()}); +#if ENABLE_VECTOR_FONT + if (UIFont::GetInstance()->IsVectorFont()) { + testCaseList_.PushBack(TestCaseInfo{"Vector_Font", new UITestVectorFont()}); + } +#endif + testCaseList_.PushBack(TestCaseInfo{"Input_Event", new UITestInputEvent()}); + testCaseList_.PushBack(TestCaseInfo{"Button", new UITestBUTTON()}); + testCaseList_.PushBack(TestCaseInfo{"UILabel", new UITestLabel()}); + testCaseList_.PushBack(TestCaseInfo{"Image", new UITestImage()}); + testCaseList_.PushBack(TestCaseInfo{"Basic_Layout", new UITestBasicLayout()}); + testCaseList_.PushBack(TestCaseInfo{"Advanced_Layout", new UITestAdvancedLayout()}); + testCaseList_.PushBack(TestCaseInfo{"ListLayout", new UITestListLayout()}); + testCaseList_.PushBack(TestCaseInfo{"UIScrollView", new UITestUIScrollView()}); + testCaseList_.PushBack(TestCaseInfo{"Box_Progress", new UITestBoxProgress()}); + testCaseList_.PushBack(TestCaseInfo{"Circle_Progress", new UITestCircleProgress()}); + testCaseList_.PushBack(TestCaseInfo{"Slider", new UITestSlider()}); + testCaseList_.PushBack(TestCaseInfo{"Animator", new UITestAnimator()}); + testCaseList_.PushBack(TestCaseInfo{"Canvas", new UITestCanvas()}); + testCaseList_.PushBack(TestCaseInfo{"Draw_Rect", new UITestDrawRect()}); + testCaseList_.PushBack(TestCaseInfo{"Draw_Line", new UITestDrawLine()}); + testCaseList_.PushBack(TestCaseInfo{"Render", new UITestRender()}); + testCaseList_.PushBack(TestCaseInfo{"Anti_Aliasing", new UITestAntiAliasing()}); + testCaseList_.PushBack(TestCaseInfo{"UIList", new UITestUIList()}); + testCaseList_.PushBack(TestCaseInfo{"UISwipeView", new UITestUISwipeView()}); + testCaseList_.PushBack(TestCaseInfo{"Image_Animator", new UITestImageAnimator()}); + testCaseList_.PushBack(TestCaseInfo{"UIPicker", new UITestUIPicker()}); + testCaseList_.PushBack(TestCaseInfo{"Font", new UITestFont()}); + testCaseList_.PushBack(TestCaseInfo{"Arc_Label", new UITestArcLabel()}); +#if ENABLE_DEBUG + testCaseList_.PushBack(TestCaseInfo{"Event_Injector", new UITestEventInjector()}); + testCaseList_.PushBack(TestCaseInfo{"Dump_Dom", new UITestDumpDomTree()}); +#ifdef VERSION_STANDARD + testCaseList_.PushBack(TestCaseInfo{"Screenshot", new UITestScreenshot()}); +#endif +#endif // ENABLE_DEBUG + testCaseList_.PushBack(TestCaseInfo{"View_Percent", new UITestViewPercent()}); + testCaseList_.PushBack(TestCaseInfo{"Texture_Mapper", new UITestTextureMapper()}); + testCaseList_.PushBack(TestCaseInfo{"Chart_Polyline", new UITestChartPolyline()}); + testCaseList_.PushBack(TestCaseInfo{"Chart_Pillar", new UITestChartPillar()}); +#if ENABLE_WINDOW + testCaseList_.PushBack(TestCaseInfo{"Dialog", new UITestDialog()}); +#endif + testCaseList_.PushBack(TestCaseInfo{"Analog_Clock", new UITestAnalogClock()}); + testCaseList_.PushBack(TestCaseInfo{"Digital_Clock", new UITestDigitalClock()}); + testCaseList_.PushBack(TestCaseInfo{"Transform", new UITestTransform()}); + testCaseList_.PushBack(TestCaseInfo{"Opacity", new UITestOpacity()}); + testCaseList_.PushBack(TestCaseInfo{"UIQrcode", new UITestQrcode()}); +#ifndef VERSION_LITE + testCaseList_.PushBack(TestCaseInfo{"Video", new UITestVideo()}); +#endif +} + +List& UITestGroup::GetTestCase() +{ + return testCaseList_; +} + +UITest* UITestGroup::GetTestCase(const char* id) +{ + if (id == nullptr) { + return nullptr; + } + ListNode* node = testCaseList_.Begin(); + while (node != testCaseList_.End()) { + if (!strcmp(id, node->data_.sliceId)) { + return node->data_.testObj; + } + node = node->next_; + } + return nullptr; +} +void UITestGroup::TearDownTestCase() +{ + ListNode* node = testCaseList_.Begin(); + while (node != testCaseList_.End()) { + delete node->data_.testObj; + node->data_.testObj = nullptr; + node = node->next_; + } + testCaseList_.Clear(); +} +} // namespace OHOS diff --git a/test/uitest/test_animator/ui_test_animator.cpp b/test/uitest/test_animator/ui_test_animator.cpp new file mode 100755 index 0000000..73c8f54 --- /dev/null +++ b/test/uitest/test_animator/ui_test_animator.cpp @@ -0,0 +1,310 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "ui_test_animator.h" +#include "common/screen.h" +#include "components/ui_label.h" +#include "test_resource_config.h" + +namespace OHOS { +namespace { +const int16_t LABEL_HEIGHT = 29; +const int16_t BUTTON_WIDTH = BUTTON_WIDHT3; +const int16_t BUTTON_HEIGHT = BUTTON_HEIGHT3; +const int16_t DELTA_X_COORDINATE = 5; +const int16_t DELTA_Y_COORDINATE = 12; +} // namespace + +void UITestAnimator::SetUp() +{ + if (container_ == nullptr) { + container_ = new UIScrollView(); + container_->Resize(Screen::GetInstance().GetWidth(), Screen::GetInstance().GetHeight() - BACK_BUTTON_HEIGHT); + uiViewGroupFrame_ = new UIViewGroup(); + uiViewGroupFrame_->SetStyle(STYLE_BORDER_COLOR, Color::White().full); + uiViewGroupFrame_->SetStyle(STYLE_BORDER_OPA, HALF_OPA_OPAQUE); + uiViewGroupFrame_->SetStyle(STYLE_BORDER_WIDTH, VIEW_STYLE_BORDER_WIDTH); + uiViewGroupFrame_->SetStyle(STYLE_BORDER_RADIUS, VIEW_STYLE_BORDER_RADIUS); + uiViewGroupFrame_->SetStyle(STYLE_BACKGROUND_OPA, 0); + uiViewGroupFrame_->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE2, VIEW_DISTANCE_TO_TOP_SIDE); + container_->Add(uiViewGroupFrame_); + UILabel* label = new UILabel(); + container_->Add(label); + // 264: label width; 48: label height + label->SetPosition(TEXT_DISTANCE_TO_LEFT_SIDE, TEXT_DISTANCE_TO_TOP_SIDE, 264, 48); + label->SetText("动画效果"); + label->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); + image_ = new UIImageView(); + image_->SetSrc(RED_IMAGE_PATH); + image_->SetPosition(0, 5); // 5:y-coordinate + callback_ = new ImageEaseAnimatorCallback(image_, 0, 338); // 338:endPos + animator_ = callback_->GetAnimator(); + uiViewGroupFrame_->Add(image_); + uiViewGroupFrame_->Resize(Screen::GetInstance().GetWidth() - VIEW_DISTANCE_TO_LEFT_SIDE, + image_->GetHeight() + 10); // 10: increase y-coordinate + } + if (scroll_ == nullptr) { + scroll_ = new UIScrollView(); + // 20: increase y-coordinate + uint16_t y = uiViewGroupFrame_->GetY() + uiViewGroupFrame_->GetHeight() + 20; + scroll_->SetPosition(0, y, Screen::GetInstance().GetWidth(), + Screen::GetInstance().GetHeight() - y - 64); // 64: decrease y-coordinate + container_->Add(scroll_); + positionX_ = 0; + } +} + +void UITestAnimator::TearDown() +{ + DeleteChildren(container_); + container_ = nullptr; + image_ = nullptr; + scroll_ = nullptr; + delete callback_; + callback_ = nullptr; + uiViewGroupFrame_ = nullptr; +} + +UIView* UITestAnimator::GetTestView() +{ + UIKit_Animator_Test_BackEasing_001(); + UIKit_Animator_Test_CircEasing_002(); + UIKit_Animator_Test_CubicEasing_003(); + UIKit_Animator_Test_SineEasing_004(); + UIKit_Animator_Test_QuadEasing_005(); + UIKit_Animator_Test_QuintEasing_006(); + UIKit_Animator_Test_LinearEasing_007(); + UIKit_Animator_Test_FPS_008(); + return container_; +} + +void UITestAnimator::SetUpLabel(const char* title, int16_t x, int16_t y) +{ + UILabel* label = GetTitleLabel(title); + scroll_->Add(label); + label->SetPosition(x, y, 288, LABEL_HEIGHT); // 288: label width +} + +void UITestAnimator::SetUpButton(UILabelButton* btn, const char* title, int16_t x, int16_t y) +{ + if (btn == nullptr) { + return; + } + scroll_->Add(btn); + btn->SetPosition(x, y, BUTTON_WIDHT3, BUTTON_HEIGHT3); + btn->SetText(title); + btn->SetFont(DEFAULT_VECTOR_FONT_FILENAME, BUTTON_LABEL_SIZE); + btn->SetOnClickListener(this); + btn->SetStyleForState(STYLE_BORDER_RADIUS, BUTTON_STYLE_BORDER_RADIUS_VALUE, UIButton::RELEASED); + btn->SetStyleForState(STYLE_BORDER_RADIUS, BUTTON_STYLE_BORDER_RADIUS_VALUE, UIButton::PRESSED); + btn->SetStyleForState(STYLE_BORDER_RADIUS, BUTTON_STYLE_BORDER_RADIUS_VALUE, UIButton::INACTIVE); + btn->SetStyleForState(STYLE_BACKGROUND_COLOR, BUTTON_STYLE_BACKGROUND_COLOR_VALUE, UIButton::RELEASED); + btn->SetStyleForState(STYLE_BACKGROUND_COLOR, BUTTON_STYLE_BACKGROUND_COLOR_VALUE, UIButton::PRESSED); + btn->SetStyleForState(STYLE_BACKGROUND_COLOR, BUTTON_STYLE_BACKGROUND_COLOR_VALUE, UIButton::INACTIVE); + scroll_->Invalidate(); +} + +void UITestAnimator::UIKit_Animator_Test_BackEasing_001() +{ + backOvershootBtn_ = new UILabelButton(); + backEaseInBtn_ = new UILabelButton(); + backEaseOutBtn_ = new UILabelButton(); + backEaseInOutBtn_ = new UILabelButton(); + positionX_ = TEXT_DISTANCE_TO_LEFT_SIDE; + positionY_ = 0; + SetUpLabel("back动画效果: ", positionX_, positionY_); + positionY_ += LABEL_HEIGHT + DELTA_X_COORDINATE; + SetUpButton(backOvershootBtn_, "overshoot+", positionX_, positionY_); + positionX_ += BUTTON_WIDTH + DELTA_Y_COORDINATE; + SetUpButton(backEaseInBtn_, "BackEaseIn", positionX_, positionY_); + positionX_ = TEXT_DISTANCE_TO_LEFT_SIDE; + positionY_ += BUTTON_HEIGHT + DELTA_Y_COORDINATE; + SetUpButton(backEaseOutBtn_, "BackEaseOut", positionX_, positionY_); + positionX_ += BUTTON_WIDTH + DELTA_Y_COORDINATE; + SetUpButton(backEaseInOutBtn_, "BackEaseInOut", positionX_, positionY_); +} + +void UITestAnimator::UIKit_Animator_Test_CircEasing_002() +{ + circEaseInBtn_ = new UILabelButton(); + circEaseOutBtn_ = new UILabelButton(); + circEaseInOutBtn_ = new UILabelButton(); + // 2: half of screen width + positionX_ = Screen::GetInstance().GetWidth() / 2 + TEXT_DISTANCE_TO_LEFT_SIDE; + positionY_ = 0; + SetUpLabel("circ动画效果: ", positionX_, positionY_); + positionY_ += LABEL_HEIGHT + DELTA_X_COORDINATE; + SetUpButton(circEaseInBtn_, "CircEaseIn", positionX_, positionY_); + positionX_ += BUTTON_WIDTH + DELTA_Y_COORDINATE; + SetUpButton(circEaseOutBtn_, "CircEaseOut", positionX_, positionY_); + // 2: half of screen width + positionX_ = Screen::GetInstance().GetWidth() / 2 + TEXT_DISTANCE_TO_LEFT_SIDE; + positionY_ += BUTTON_HEIGHT + DELTA_Y_COORDINATE; + SetUpButton(circEaseInOutBtn_, "CircEaseInOut", positionX_, positionY_); +} + +void UITestAnimator::UIKit_Animator_Test_CubicEasing_003() +{ + cubicEaseInBtn_ = new UILabelButton(); + cubicEaseOutBtn_ = new UILabelButton(); + cubicEaseInOutBtn_ = new UILabelButton(); + positionX_ = TEXT_DISTANCE_TO_LEFT_SIDE; + positionY_ = 148; // 148: y-coordinate + SetUpLabel("cubic动画效果: ", positionX_, positionY_); + positionY_ += LABEL_HEIGHT + DELTA_X_COORDINATE; + SetUpButton(cubicEaseInBtn_, "CubicEaseIn", positionX_, positionY_); + positionX_ += BUTTON_WIDTH + DELTA_Y_COORDINATE; + SetUpButton(cubicEaseOutBtn_, "CubicEaseOut", positionX_, positionY_); + positionX_ = TEXT_DISTANCE_TO_LEFT_SIDE; + positionY_ += BUTTON_HEIGHT + DELTA_Y_COORDINATE; + SetUpButton(cubicEaseInOutBtn_, "CubicEaseInOut", positionX_, positionY_); +} + +void UITestAnimator::UIKit_Animator_Test_SineEasing_004() +{ + sineEaseInBtn_ = new UILabelButton(); + sineEaseOutBtn_ = new UILabelButton(); + sineEaseInOutBtn_ = new UILabelButton(); + // 2: half of screen width + positionX_ = Screen::GetInstance().GetWidth() / 2 + TEXT_DISTANCE_TO_LEFT_SIDE; + positionY_ = 148; // 148: y-coordinate + SetUpLabel("sine动画效果: ", positionX_, positionY_); + positionY_ += LABEL_HEIGHT + DELTA_X_COORDINATE; + SetUpButton(sineEaseInBtn_, "SineEaseIn", positionX_, positionY_); + positionX_ += BUTTON_WIDTH + DELTA_Y_COORDINATE; + SetUpButton(sineEaseOutBtn_, "SineEaseOut", positionX_, positionY_); + // 2: half of screen width + positionX_ = Screen::GetInstance().GetWidth() / 2 + TEXT_DISTANCE_TO_LEFT_SIDE; + positionY_ += BUTTON_HEIGHT + DELTA_Y_COORDINATE; + SetUpButton(sineEaseInOutBtn_, "SineEaseInOut", positionX_, positionY_); +} + +void UITestAnimator::UIKit_Animator_Test_QuadEasing_005() +{ + quadEaseInBtn_ = new UILabelButton(); + quadEaseOutBtn_ = new UILabelButton(); + quadEaseInOutBtn_ = new UILabelButton(); + positionX_ = TEXT_DISTANCE_TO_LEFT_SIDE; + positionY_ = 296; // 296: y-coordinate + SetUpLabel("quad动画效果: ", positionX_, positionY_); + positionY_ += LABEL_HEIGHT + DELTA_X_COORDINATE; + SetUpButton(quadEaseInBtn_, "QuadEaseIn", positionX_, positionY_); + positionX_ += BUTTON_WIDTH + DELTA_Y_COORDINATE; + SetUpButton(quadEaseOutBtn_, "QuadEaseOut", positionX_, positionY_); + positionX_ = TEXT_DISTANCE_TO_LEFT_SIDE; + positionY_ += BUTTON_HEIGHT + DELTA_Y_COORDINATE; + SetUpButton(quadEaseInOutBtn_, "QuadEaseInOut", positionX_, positionY_); +} + +void UITestAnimator::UIKit_Animator_Test_QuintEasing_006() +{ + quintEaseInBtn_ = new UILabelButton(); + quintEaseOutBtn_ = new UILabelButton(); + quintEaseInOutBtn_ = new UILabelButton(); + // 2: half of screen width + positionX_ = Screen::GetInstance().GetWidth() / 2 + TEXT_DISTANCE_TO_LEFT_SIDE; + positionY_ = 296; // 296: y-coordinate + SetUpLabel("quint动画效果: ", positionX_, positionY_); + positionY_ += LABEL_HEIGHT + DELTA_X_COORDINATE; + SetUpButton(quintEaseInBtn_, "QuintEaseIn", positionX_, positionY_); + positionX_ += BUTTON_WIDTH + DELTA_Y_COORDINATE; + SetUpButton(quintEaseOutBtn_, "QuintEaseOut", positionX_, positionY_); + // 2: half of screen width + positionX_ = Screen::GetInstance().GetWidth() / 2 + TEXT_DISTANCE_TO_LEFT_SIDE; + positionY_ += BUTTON_HEIGHT + DELTA_Y_COORDINATE; + SetUpButton(quintEaseInOutBtn_, "QuintEaseInOut", positionX_, positionY_); +} + +void UITestAnimator::UIKit_Animator_Test_LinearEasing_007() +{ + linearEaseNoneBtn_ = new UILabelButton(); + positionX_ = TEXT_DISTANCE_TO_LEFT_SIDE; + positionY_ = 444; // 444: y-coordinate + SetUpLabel("linear动画效果: ", positionX_, positionY_); + positionY_ += LABEL_HEIGHT + DELTA_X_COORDINATE; + SetUpButton(linearEaseNoneBtn_, "LinearEaseNone", positionX_, positionY_); +} + +void UITestAnimator::UIKit_Animator_Test_FPS_008() +{ + fpsLabel_ = new UILabel(); + // 90:x-coordinate, 0:y-coordinate, 90:new width, 20:new height + fpsLabel_->SetPosition(Screen::GetInstance().GetWidth() - 90, TEXT_DISTANCE_TO_TOP_SIDE, 90, + TITLE_LABEL_DEFAULT_HEIGHT); + fpsLabel_->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); + char buf[10] = "FPS"; + fpsLabel_->SetText(reinterpret_cast(buf)); + OnFPSChangedListener::SetFPSCalculateType(SysInfo::FPS_CT_PRECISE_SAMPLING); + container_->Add(fpsLabel_); + fpsLabel_->Invalidate(); +} + +bool UITestAnimator::OnClick(UIView& view, const ClickEvent& event) +{ + static double overshoot = 1.7; + if (&view == backOvershootBtn_) { + overshoot += 1; + EasingEquation::SetBackOvershoot(overshoot); + } else if (&view == backEaseInBtn_) { + callback_->SetEasingFunc(EasingEquation::BackEaseIn); + } else if (&view == backEaseOutBtn_) { + callback_->SetEasingFunc(EasingEquation::BackEaseOut); + } else if (&view == backEaseInOutBtn_) { + callback_->SetEasingFunc(EasingEquation::BackEaseInOut); + } else if (&view == circEaseInBtn_) { + callback_->SetEasingFunc(EasingEquation::CircEaseIn); + } else if (&view == circEaseOutBtn_) { + callback_->SetEasingFunc(EasingEquation::CircEaseOut); + } else if (&view == circEaseInOutBtn_) { + callback_->SetEasingFunc(EasingEquation::CircEaseInOut); + } else if (&view == cubicEaseInBtn_) { + callback_->SetEasingFunc(EasingEquation::CubicEaseIn); + } else if (&view == cubicEaseOutBtn_) { + callback_->SetEasingFunc(EasingEquation::CubicEaseOut); + } else if (&view == cubicEaseInOutBtn_) { + callback_->SetEasingFunc(EasingEquation::CubicEaseInOut); + } else if (&view == linearEaseNoneBtn_) { + callback_->SetEasingFunc(EasingEquation::LinearEaseNone); + } else if (&view == quadEaseInBtn_) { + callback_->SetEasingFunc(EasingEquation::QuadEaseIn); + } else if (&view == quadEaseOutBtn_) { + callback_->SetEasingFunc(EasingEquation::QuadEaseOut); + } else if (&view == quadEaseInOutBtn_) { + callback_->SetEasingFunc(EasingEquation::QuadEaseInOut); + } else if (&view == quintEaseInBtn_) { + callback_->SetEasingFunc(EasingEquation::QuintEaseIn); + } else if (&view == quintEaseOutBtn_) { + callback_->SetEasingFunc(EasingEquation::QuintEaseOut); + } else if (&view == quintEaseInOutBtn_) { + callback_->SetEasingFunc(EasingEquation::QuintEaseInOut); + } else if (&view == sineEaseInBtn_) { + callback_->SetEasingFunc(EasingEquation::SineEaseIn); + } else if (&view == sineEaseOutBtn_) { + callback_->SetEasingFunc(EasingEquation::SineEaseOut); + } else if (&view == sineEaseInOutBtn_) { + callback_->SetEasingFunc(EasingEquation::SineEaseInOut); + } + animator_->Start(); + container_->Invalidate(); + return true; +} + +void UITestAnimator::OnFPSChanged(float newFPS) +{ + char buf[10] = "FPS"; + fpsLabel_->SetText(reinterpret_cast(buf)); + fpsLabel_->Invalidate(); +} +} // namespace OHOS \ No newline at end of file diff --git a/test/uitest/test_animator/ui_test_animator.h b/test/uitest/test_animator/ui_test_animator.h new file mode 100755 index 0000000..6efd1a4 --- /dev/null +++ b/test/uitest/test_animator/ui_test_animator.h @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef UI_TEST_ANIMATOR_H +#define UI_TEST_ANIMATOR_H + +#include "animator/easing_equation.h" +#include "components/ui_image_view.h" +#include "components/ui_label.h" +#include "components/ui_label_button.h" +#include "components/ui_scroll_view.h" +#include "sys_info.h" +#include "ui_test.h" + +namespace OHOS { +class ImageEaseAnimatorCallback : public AnimatorCallback { +public: + ImageEaseAnimatorCallback(UIView* uiView, int16_t startPos, int16_t endPos) + : startPos_(startPos), + endPos_(endPos), + easingFunc_(EasingEquation::LinearEaseNone), + animator_(new Animator(this, uiView, 1000, true)) // 1000:duration of animator_, in milliseconds. + { + AnimatorManager::GetInstance()->Add(animator_); + } + + virtual ~ImageEaseAnimatorCallback() + { + AnimatorManager::GetInstance()->Remove(animator_); + delete animator_; + } + + Animator* GetAnimator() const + { + return animator_; + } + + void SetEasingFunc(EasingFunc easingFunc) + { + easingFunc_ = easingFunc; + } + + virtual void Callback(UIView* view) + { + if (view == nullptr) { + return; + } + int16_t pos = easingFunc_(startPos_, endPos_, animator_->GetRunTime(), animator_->GetTime()); + Rect invalidatedArea = view->GetRect(); + view->SetPosition(pos, view->GetY()); + invalidatedArea.Join(invalidatedArea, view->GetRect()); + view->InvalidateRect(invalidatedArea); + } + +protected: + int16_t startPos_; + int16_t endPos_; + EasingFunc easingFunc_; + Animator* animator_; +}; + +class UITestAnimator : public UITest, public UIView::OnClickListener, public SysInfo::OnFPSChangedListener { +public: + UITestAnimator() {} + ~UITestAnimator(){}; + void SetUp() override; + void TearDown() override; + UIView* GetTestView() override; + + void SetUpButton(UILabelButton* btn, const char* title, int16_t x, int16_t y); + void SetUpLabel(const char* title, int16_t x, int16_t y); + + bool OnClick(UIView& view, const ClickEvent& event) override; + void OnFPSChanged(float newFPS) override; + + void UIKit_Animator_Test_BackEasing_001(); + void UIKit_Animator_Test_CircEasing_002(); + void UIKit_Animator_Test_CubicEasing_003(); + void UIKit_Animator_Test_SineEasing_004(); + void UIKit_Animator_Test_QuadEasing_005(); + void UIKit_Animator_Test_QuintEasing_006(); + void UIKit_Animator_Test_LinearEasing_007(); + void UIKit_Animator_Test_FPS_008(); + +private: + UIScrollView* container_ = nullptr; + UIScrollView* scroll_ = nullptr; + UIImageView* image_ = nullptr; + ImageEaseAnimatorCallback* callback_ = nullptr; + Animator* animator_ = nullptr; + UIViewGroup* uiViewGroupFrame_ = nullptr; + + UILabelButton* backOvershootBtn_ = nullptr; + UILabelButton* backEaseInBtn_ = nullptr; + UILabelButton* backEaseOutBtn_ = nullptr; + UILabelButton* backEaseInOutBtn_ = nullptr; + UILabelButton* circEaseInBtn_ = nullptr; + UILabelButton* circEaseOutBtn_ = nullptr; + UILabelButton* circEaseInOutBtn_ = nullptr; + UILabelButton* cubicEaseInBtn_ = nullptr; + UILabelButton* cubicEaseOutBtn_ = nullptr; + UILabelButton* cubicEaseInOutBtn_ = nullptr; + UILabelButton* linearEaseNoneBtn_ = nullptr; + UILabelButton* quadEaseInBtn_ = nullptr; + UILabelButton* quadEaseOutBtn_ = nullptr; + UILabelButton* quadEaseInOutBtn_ = nullptr; + UILabelButton* quintEaseInBtn_ = nullptr; + UILabelButton* quintEaseOutBtn_ = nullptr; + UILabelButton* quintEaseInOutBtn_ = nullptr; + UILabelButton* sineEaseInBtn_ = nullptr; + UILabelButton* sineEaseOutBtn_ = nullptr; + UILabelButton* sineEaseInOutBtn_ = nullptr; + UILabel* fpsLabel_ = nullptr; +}; +} // namespace OHOS +#endif // UI_TEST_ANIMATOR_H diff --git a/test/uitest/test_anti_aliasing/ui_test_anti_aliasing.cpp b/test/uitest/test_anti_aliasing/ui_test_anti_aliasing.cpp new file mode 100755 index 0000000..406edd8 --- /dev/null +++ b/test/uitest/test_anti_aliasing/ui_test_anti_aliasing.cpp @@ -0,0 +1,167 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "ui_test_anti_aliasing.h" +#include "common/screen.h" +#include "components/ui_canvas.h" +#include "components/ui_circle_progress.h" +#include "components/ui_label.h" +#include "components/ui_view_group.h" + +namespace OHOS { +void UITestAntiAliasing::SetUp() +{ + if (container_ == nullptr) { + container_ = new UIScrollView(); + container_->Resize(Screen::GetInstance().GetWidth(), Screen::GetInstance().GetHeight() - BACK_BUTTON_HEIGHT); + container_->SetHorizontalScrollState(false); + } +} + +void UITestAntiAliasing::TearDown() +{ + DeleteChildren(container_); + container_ = nullptr; +} + +UIView* UITestAntiAliasing::GetTestView() +{ + UIKit_Anti_Aliasing_Test_Rect_001(); + UIKit_Anti_Aliasing_Test_Circle_001(); + UIKit_Anti_Aliasing_Test_Line_001(); + return container_; +} + +UIViewGroup* UITestAntiAliasing::CreateTestCaseGroup() const +{ + UIViewGroup* group = new UIViewGroup(); + group->Resize(Screen::GetInstance().GetWidth(), 200); // 200: group height + return group; +} + +UILabel* UITestAntiAliasing::CreateTitleLabel() const +{ + UILabel* label = new UILabel(); + // 2: half of screen width + label->SetPosition(TEXT_DISTANCE_TO_LEFT_SIDE, 0, Screen::GetInstance().GetWidth() / 2, TITLE_LABEL_DEFAULT_HEIGHT); + label->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); + return label; +} + +void UITestAntiAliasing::UIKit_Anti_Aliasing_Test_Rect_001() +{ + if (container_ == nullptr) { + return; + } + + UIViewGroup* group = CreateTestCaseGroup(); + // 2: half of screen width, 110: group height + group->Resize(Screen::GetInstance().GetWidth() / 2, 110); + group->SetViewId("UIKit_Draw_Rect_Test_Rect_001"); + group->SetPosition(0, 0); + + UILabel* label = CreateTitleLabel(); + label->SetText("矩形抗锯齿效果:"); + label->SetPosition(TEXT_DISTANCE_TO_LEFT_SIDE, TEXT_DISTANCE_TO_TOP_SIDE); + group->Add(label); + + UIView* view = new UIView(); + Style style = view->GetStyleConst(); + style.bgColor_ = Color::Green(); + style.bgOpa_ = OPA_OPAQUE; + style.borderRadius_ = 5; // 5:border radius + style.borderColor_ = Color::Gray(); + style.borderOpa_ = OPA_OPAQUE; + style.borderWidth_ = 3; // 3:border width + view->SetStyle(style); + view->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE, VIEW_DISTANCE_TO_TOP_SIDE); + view->Resize(120, 50); // 120:new width, 50:new width + group->Add(view); + + container_->Add(group); +} + +void UITestAntiAliasing::UIKit_Anti_Aliasing_Test_Circle_001() +{ + if (container_ == nullptr) { + return; + } + + UIViewGroup* group = CreateTestCaseGroup(); + // 336: x-coordinate + group->SetPosition(336, 0); + // 2: half of screen width; 180: group height + group->Resize(Screen::GetInstance().GetWidth() / 2, 180); + group->SetViewId("UIKit_Anti_Aliasing_Test_Circle_001"); + + UILabel* label = CreateTitleLabel(); + label->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE2, TEXT_DISTANCE_TO_TOP_SIDE); + label->SetText("弧形/圆形抗锯齿效果:"); + group->Add(label); + + UICircleProgress* circleProgress = new UICircleProgress(); + circleProgress->SetPosition(0, 23, 150, 150); // 23:y-coordinate, 150:new width, 150:new height + circleProgress->SetCenterPosition(75, 75); // 75:x-coordinate, 75:y-coordinate + circleProgress->SetRadius(50); // 50:outer radius + circleProgress->SetValue(20); // 20:current value of progress bar + circleProgress->SetLineColor(Color::White()); + group->Add(circleProgress); + + UICircleProgress* circleProgress1 = new UICircleProgress(); + circleProgress1->SetPosition(130, 23, 150, 150); // 130:x-coordinate, 23:y-coordinate, 150:new width, 150:new height + circleProgress1->SetCenterPosition(75, 75); // 75:x-coordinate, 75:y-coordinate + circleProgress1->SetRadius(50); // 50:outer radius + circleProgress1->SetValue(100); // 100:current value of progress bar + circleProgress1->SetLineColor(Color::White()); + group->Add(circleProgress1); + + container_->Add(group); +} + +void UITestAntiAliasing::UIKit_Anti_Aliasing_Test_Line_001() +{ + if (container_ == nullptr) { + return; + } + + UIViewGroup* group = CreateTestCaseGroup(); + // 648: x-coordinate + group->SetPosition(648, 0); + group->Resize(Screen::GetInstance().GetWidth() / 2, 250); // 2: half of screen width; // 250: y-coordinate + group->SetViewId("UIKit_Anti_Aliasing_Test_Line_001"); + + UILabel* label = CreateTitleLabel(); + label->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE2, TEXT_DISTANCE_TO_TOP_SIDE); + label->SetText("直线抗锯齿效果:"); + group->Add(label); + + UICanvas* canvas = new UICanvas(); + canvas->SetHeight(200); // 200:height + canvas->SetWidth(200); // 200:width + canvas->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE2, VIEW_DISTANCE_TO_TOP_SIDE); + canvas->SetStyle(STYLE_BACKGROUND_COLOR, Color::Gray().full); + Paint paint; + // 0:start point x-coordinate, 50:start point y-coordinate, 150:end point x-coordinate, 150:end point y-coordinate + canvas->DrawLine({0, 50}, {150, 50}, paint); + // 0:start point x-coordinate, 50:start point y-coordinate, 150:end point x-coordinate, 150:end point y-coordinate + canvas->DrawLine({0, 50}, {150, 100}, paint); + // 0:start point x-coordinate, 50:start point y-coordinate, 150:end point x-coordinate, 150:end point y-coordinate + canvas->DrawLine({0, 50}, {150, 200}, paint); + // 0:start point x-coordinate, 50:start point y-coordinate, 150:end point x-coordinate, 150:end point y-coordinate + canvas->DrawLine({0, 50}, {100, 200}, paint); + group->Add(canvas); + container_->Add(group); +} +} // namespace OHOS \ No newline at end of file diff --git a/test/uitest/test_anti_aliasing/ui_test_anti_aliasing.h b/test/uitest/test_anti_aliasing/ui_test_anti_aliasing.h new file mode 100755 index 0000000..94d3cb3 --- /dev/null +++ b/test/uitest/test_anti_aliasing/ui_test_anti_aliasing.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef UI_TEST_ANTI_ALIASING_H +#define UI_TEST_ANTI_ALIASING_H + +#include "components/ui_label.h" +#include "components/ui_scroll_view.h" +#include "ui_test.h" + +namespace OHOS { +class UITestAntiAliasing : public UITest { +public: + UITestAntiAliasing() {} + ~UITestAntiAliasing() {} + void SetUp() override; + void TearDown() override; + UIView* GetTestView() override; + + /** + * @brief Test if rect anti-aliasing + */ + void UIKit_Anti_Aliasing_Test_Rect_001(); + + /** + * @brief Test if circle anti-aliasing + */ + void UIKit_Anti_Aliasing_Test_Circle_001(); + + /** + * @brief Test if line anti-aliasing + */ + void UIKit_Anti_Aliasing_Test_Line_001(); + +private: + UIViewGroup* CreateTestCaseGroup() const; + UILabel* CreateTitleLabel() const; + UIScrollView* container_ = nullptr; +}; +} // namespace OHOS +#endif // UI_TEST_ANTI_ALIASING_H diff --git a/test/uitest/test_arc_label/ui_test_arc_label.cpp b/test/uitest/test_arc_label/ui_test_arc_label.cpp new file mode 100755 index 0000000..ca03ca8 --- /dev/null +++ b/test/uitest/test_arc_label/ui_test_arc_label.cpp @@ -0,0 +1,200 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "ui_test_arc_label.h" +#include "common/screen.h" +#include "font/ui_font.h" + +namespace OHOS { +namespace { +const int16_t GAP = 5; +const int16_t TITLE_HEIGHT = 29; +const uint16_t CENTER_X = 185; +const uint16_t CENTER_Y = 155; +const uint16_t RADIUS = 150; +} // namespace + +void UITestArcLabel::SetUp() +{ + if (container_ == nullptr) { + container_ = new UIScrollView(); + container_->SetThrowDrag(true); + container_->SetHorizontalScrollState(false); + container_->Resize(Screen::GetInstance().GetWidth(), Screen::GetInstance().GetHeight() - BACK_BUTTON_HEIGHT); + positionX_ = 0; + positionY_ = 0; + } +} + +void UITestArcLabel::TearDown() +{ + DeleteChildren(container_); + container_ = nullptr; +} + +void UITestArcLabel::InnerTestTitle(const char* title, int16_t x, int16_t y) const +{ + UILabel* titleLabel = new UILabel(); + titleLabel->SetPosition(x, y, Screen::GetInstance().GetWidth(), TITLE_HEIGHT); + titleLabel->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); + titleLabel->SetText(title); + container_->Add(titleLabel); +} + +UIView* UITestArcLabel::GetTestView() +{ + UIKit_UIArcLabel_Test_Display_001(); + UIKit_UIArcLabel_Test_Display_002(); + UIKit_UIArcLabel_Test_Display_003(); + UIKit_UIArcLabel_Test_Display_004(); + + UIKit_UIArcLabel_Test_Align_001(); + UIKit_UIArcLabel_Test_Align_002(); + UIKit_UIArcLabel_Test_Align_003(); + return container_; +} + +void UITestArcLabel::UIKit_UIArcLabel_Test_Display_001() +{ + const char* title = "显示内部角度从0到270的弧形文本 "; + // 0: start angle 270: end angle + TestArcLabelDisplay(title, 0, 270, UIArcLabel::TextOrientation::INSIDE, VIEW_DISTANCE_TO_LEFT_SIDE, + VIEW_DISTANCE_TO_TOP_SIDE); +} + +void UITestArcLabel::UIKit_UIArcLabel_Test_Display_002() +{ + const char* title = "显示内部角度从0到-270的弧形文本 "; + // 0: start angle -270: end angle 100: y-coordinate + TestArcLabelDisplay(title, 0, -270, UIArcLabel::TextOrientation::INSIDE, VIEW_DISTANCE_TO_LEFT_SIDE, 100); +} + +void UITestArcLabel::UIKit_UIArcLabel_Test_Display_003() +{ + const char* title = "显示外部角度从0到270的弧形文本 "; + // 0: start angle 270: end angle 200: y-coordinate + TestArcLabelDisplay(title, 0, 270, UIArcLabel::TextOrientation::OUTSIDE, VIEW_DISTANCE_TO_LEFT_SIDE, 200); +} + +void UITestArcLabel::UIKit_UIArcLabel_Test_Display_004() +{ + const char* title = "显示外部角度从0到-270的弧形文本 "; + // 0: start angle -270: end angle 300: y-coordinate + TestArcLabelDisplay(title, 0, -270, UIArcLabel::TextOrientation::OUTSIDE, VIEW_DISTANCE_TO_LEFT_SIDE, 300); +} + +void UITestArcLabel::TestArcLabelDisplay(const char* title, + const int16_t startAngle, + const int16_t endAngle, + const UIArcLabel::TextOrientation orientation, + int16_t x, + int16_t y) +{ + if (container_ != nullptr) { + InnerTestTitle(title, x, positionY_); + UIArcLabel* label = new UIArcLabel(); + label->SetArcTextCenter(CENTER_X, CENTER_Y + positionY_ + GAP * 4); // 4: 4 times GAP + label->SetArcTextRadius(RADIUS); + label->SetArcTextAngle(startAngle, endAngle); + label->SetArcTextOrientation(orientation); + label->SetFont(DEFAULT_VECTOR_FONT_FILENAME, 30); // 30: font size + label->SetText("012345678ABCDEF0123456789ABCDE"); + label->SetStyle(STYLE_LETTER_SPACE, 10); // 10: space + container_->Add(label); + positionY_ += (RADIUS * 2) + GAP + TITLE_HEIGHT; // 2: diameter + } +} + +void UITestArcLabel::UIKit_UIArcLabel_Test_Align_001() +{ + if (container_ != nullptr) { + // 2: half of screen width + positionX_ = Screen::GetInstance().GetWidth() / 2 + VIEW_DISTANCE_TO_LEFT_SIDE; + positionY_ = 0; + InnerTestTitle("弧形文本在0到90度之间左对齐 ", positionX_, positionY_); + positionY_ += TITLE_HEIGHT + GAP; + UIView* back = new UIView(); + back->SetPosition(positionX_, positionY_ + GAP); + back->Resize(RADIUS, RADIUS); + back->SetStyle(STYLE_BACKGROUND_COLOR, Color::Gray().full); + back->SetStyle(STYLE_BACKGROUND_OPA, OPA_OPAQUE); + + UIArcLabel* label = new UIArcLabel(); + label->SetArcTextCenter(positionX_, CENTER_Y + positionY_); + label->SetArcTextRadius(RADIUS); + label->SetArcTextAngle(0, 90); // 0: start angle, 90: end angle + label->SetFont(DEFAULT_VECTOR_FONT_FILENAME, 30); // 30: font size + label->SetText("LEFT"); + label->SetAlign(UITextLanguageAlignment::TEXT_ALIGNMENT_LEFT); + label->SetStyle(STYLE_LETTER_SPACE, 6); // 6: space + + container_->Add(back); + container_->Add(label); + positionY_ += RADIUS + GAP + TITLE_HEIGHT; + } +} + +void UITestArcLabel::UIKit_UIArcLabel_Test_Align_002() +{ + if (container_ != nullptr) { + InnerTestTitle("弧形文本在0到90度之间居中对齐 ", positionX_, positionY_); + positionY_ += TITLE_HEIGHT + GAP; + UIView* back = new UIView(); + back->SetPosition(positionX_, positionY_ + GAP); + back->Resize(RADIUS, RADIUS); + back->SetStyle(STYLE_BACKGROUND_COLOR, Color::Gray().full); + back->SetStyle(STYLE_BACKGROUND_OPA, OPA_OPAQUE); + + UIArcLabel* label = new UIArcLabel(); + label->SetArcTextCenter(positionX_, CENTER_Y + positionY_); + label->SetArcTextRadius(RADIUS); + label->SetArcTextAngle(0, 90); // 0: start angle, 90: end angle + label->SetFont(DEFAULT_VECTOR_FONT_FILENAME, 30); // 30: font size + label->SetText("CENTER"); + label->SetAlign(UITextLanguageAlignment::TEXT_ALIGNMENT_CENTER); + label->SetStyle(STYLE_LETTER_SPACE, 6); // 6: space + + container_->Add(back); + container_->Add(label); + positionY_ += RADIUS + GAP + TITLE_HEIGHT; + } +} + +void UITestArcLabel::UIKit_UIArcLabel_Test_Align_003() +{ + if (container_ != nullptr) { + InnerTestTitle("弧形文本在0到90度之间右对齐 ", positionX_, positionY_); + positionY_ += TITLE_HEIGHT + GAP; + UIView* back = new UIView(); + back->SetPosition(positionX_, positionY_ + GAP); + back->Resize(RADIUS, RADIUS); + back->SetStyle(STYLE_BACKGROUND_COLOR, Color::Gray().full); + back->SetStyle(STYLE_BACKGROUND_OPA, OPA_OPAQUE); + + UIArcLabel* label = new UIArcLabel(); + label->SetArcTextCenter(positionX_, CENTER_Y + positionY_); + label->SetArcTextRadius(RADIUS); + label->SetArcTextAngle(0, 90); // 0: start angle, 90: end angle + label->SetFont(DEFAULT_VECTOR_FONT_FILENAME, 30); // 30: font size + label->SetText("RIGHT"); + label->SetAlign(UITextLanguageAlignment::TEXT_ALIGNMENT_RIGHT); + label->SetStyle(STYLE_LETTER_SPACE, 6); // 6: space + + container_->Add(back); + container_->Add(label); + positionY_ += RADIUS + GAP + TITLE_HEIGHT; + } +} +} // namespace OHOS \ No newline at end of file diff --git a/test/uitest/test_arc_label/ui_test_arc_label.h b/test/uitest/test_arc_label/ui_test_arc_label.h new file mode 100755 index 0000000..a03b441 --- /dev/null +++ b/test/uitest/test_arc_label/ui_test_arc_label.h @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef UI_TEST_ARC_LABEL_H +#define UI_TEST_ARC_LABEL_H + +#include "components/ui_arc_label.h" +#include "components/ui_label.h" +#include "components/ui_scroll_view.h" +#include "ui_test.h" + +namespace OHOS { +class UITestArcLabel : public UITest { +public: + UITestArcLabel() {} + ~UITestArcLabel() {} + void SetUp() override; + void TearDown() override; + UIView* GetTestView() override; + + /** + * @brief Test display arc text from 0 to 270 INSIDE + */ + void UIKit_UIArcLabel_Test_Display_001(); + + /** + * @brief Test display arc text from 270 to 0 INSIDE + */ + void UIKit_UIArcLabel_Test_Display_002(); + + /** + * @brief Test display arc text from 0 to 270 OUTSIDE + */ + void UIKit_UIArcLabel_Test_Display_003(); + + /** + * @brief Test display arc text from 270 to 0 OUTSIDE + */ + void UIKit_UIArcLabel_Test_Display_004(); + + /** + * @brief Test arc text align LEFT + */ + void UIKit_UIArcLabel_Test_Align_001(); + + /** + * @brief Test arc text align CENTER + */ + void UIKit_UIArcLabel_Test_Align_002(); + + /** + * @brief Test arc text align RIGHT + */ + void UIKit_UIArcLabel_Test_Align_003(); + +private: + UIScrollView* container_ = nullptr; + + void InnerTestTitle(const char* title, int16_t x, int16_t y) const; + + // for direction and orientation + void TestArcLabelDisplay(const char* title, const int16_t startAngle, const int16_t endAngle, + const UIArcLabel::TextOrientation orientation, int16_t x, int16_t y); +}; +} // namespace OHOS +#endif // UI_TEST_ARC_LABEL_H diff --git a/test/uitest/test_button/ui_test_button.cpp b/test/uitest/test_button/ui_test_button.cpp new file mode 100755 index 0000000..d7c31f5 --- /dev/null +++ b/test/uitest/test_button/ui_test_button.cpp @@ -0,0 +1,671 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "ui_test_button.h" +#include "common/screen.h" +#include "components/root_view.h" +#include "components/ui_checkbox.h" +#include "components/ui_digital_clock.h" +#include "components/ui_label.h" +#include "components/ui_label_button.h" +#include "components/ui_radio_button.h" +#include "components/ui_toggle_button.h" +#include "font/ui_font.h" +#include "test_resource_config.h" + +namespace OHOS { +void UITestBUTTON::SetUp() +{ + if (container_ == nullptr) { + container_ = new UIScrollView(); + container_->Resize(Screen::GetInstance().GetWidth(), Screen::GetInstance().GetHeight() - BACK_BUTTON_HEIGHT); + container_->SetHorizontalScrollState(false); + } +} + +void UITestBUTTON::TearDown() +{ + DeleteChildren(container_); + container_ = nullptr; +} + +UIView* UITestBUTTON::GetTestView() +{ + UIKit_Check_Box_Test_001(); + UIKit_Radio_Button_Test_001(); + UIKit_Toggle_Button_Test_001(); + UIKit_Check_Box_Test_002(); + UIKit_Radio_Button_Test_002(); + UIKit_Toggle_Button_Test_002(); + UIKit_Button_Test_001(); + return container_; +} + +void UITestBUTTON::UIKit_Check_Box_Test_001() const +{ + if (container_ != nullptr) { + UILabel* label = new UILabel(); + container_->Add(label); + label->SetPosition(TEXT_DISTANCE_TO_LEFT_SIDE, 5, // 5: y-coordinate + Screen::GetInstance().GetWidth(), TITLE_LABEL_DEFAULT_HEIGHT); + label->SetText("checkbox功能"); + label->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); + + UICheckBox* checkbox = new UICheckBox(); + checkbox->SetPosition(30, 30); // 30: x-coordinate, 30: y-coordinate + + UICheckBox* checkbox2 = new UICheckBox(); + checkbox2->SetPosition(100, 30); // 100: x-coordinate, 30: y-coordinate + + UICheckBox* checkbox3 = new UICheckBox(); + checkbox3->SetPosition(170, 30); // 170: x-coordinate, 30: y-coordinate + + container_->Add(checkbox); + container_->Add(checkbox2); + container_->Add(checkbox3); + } +} + +void UITestBUTTON::UIKit_Radio_Button_Test_001() const +{ + if (container_ != nullptr) { + UILabel* label = new UILabel(); + container_->Add(label); + // 0:x-coordinate, 130:y-coordinate, 20:new height + label->SetPosition(TEXT_DISTANCE_TO_LEFT_SIDE, 130, Screen::GetInstance().GetWidth(), + TITLE_LABEL_DEFAULT_HEIGHT); + label->SetText("radiobutton功能"); + label->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); + + UIRadioButton* radioButton = new UIRadioButton("aaa"); + radioButton->SetPosition(0, 10); // 0: x-coordinate, 10: y-coordinate + + UIRadioButton* radioButton2 = new UIRadioButton("aaa"); + radioButton2->SetPosition(50, 10); // 50: x-coordinate, 10: y-coordinate + radioButton2->SetWidth(40); // 40: width + radioButton2->SetHeight(30); // 30: height + + UIRadioButton* radioButton3 = new UIRadioButton("aaa"); + radioButton3->SetPosition(110, 10); // 110: x-coordinate, 10: y-coordinate + radioButton3->SetWidth(80); // 80: width + radioButton3->SetHeight(60); // 60: height + + UIRadioButton* radioButton4 = new UIRadioButton("aaa"); + radioButton4->SetPosition(10, 10); // 10: x-coordinate, 10: y-coordinate + radioButton4->SetWidth(70); // 70: width + radioButton4->SetHeight(90); // 90: width + + UIRadioButton* radioButton5 = new UIRadioButton("aaa"); + radioButton5->SetPosition(110, 10); // 110: x-coordinate, 10: y-coordinate + radioButton5->SetWidth(-1); // -1: width + radioButton5->SetHeight(90); // 90: width + + UIRadioButton* radioButton6 = new UIRadioButton("aaa"); + radioButton6->SetPosition(130, 10); // 130: x-coordinate, 10: y-coordinate + radioButton6->SetWidth(0); // 0: width + radioButton6->SetHeight(0); // 0: width + + UIRadioButton* radioButton7 = new UIRadioButton("aaa"); + radioButton7->SetPosition(140, 10); // 140: x-coordinate, 10: y-coordinate + radioButton7->SetWidth(1000); // 1000: width + radioButton7->SetHeight(50); // 50: width + + OHOS::UIViewGroup* viewGroup = new UIViewGroup(); + viewGroup->SetPosition(30, 150); // 30: x-coordinate, 150: y-coordinate + viewGroup->SetWidth(Screen::GetInstance().GetWidth() / 2); // 2: half width + viewGroup->SetHeight(Screen::GetInstance().GetHeight() / 2); // 2: half height + + OHOS::UIViewGroup* viewGroup2 = new UIViewGroup(); + // 40, increase width, 2: half width, 150: y-coordinate + viewGroup2->SetPosition(40 + Screen::GetInstance().GetWidth() / 2, 150); + viewGroup2->SetWidth(Screen::GetInstance().GetWidth() / 2); // 2: half width + viewGroup2->SetHeight(Screen::GetInstance().GetHeight() / 2); // 2: half height + + viewGroup2->Add(radioButton4); + viewGroup2->Add(radioButton5); + viewGroup2->Add(radioButton6); + viewGroup2->Add(radioButton7); + + viewGroup->Add(radioButton); + viewGroup->Add(radioButton2); + viewGroup->Add(radioButton3); + viewGroup->SetStyle(STYLE_BACKGROUND_OPA, 0); + + container_->Add(viewGroup); + container_->Add(viewGroup2); + } +} + +class TestBtnOnStateChangeListener : public OHOS::UICheckBox::OnChangeListener { +public: + explicit TestBtnOnStateChangeListener(UIView* uiView) + { + uiView_ = uiView; + } + + ~TestBtnOnStateChangeListener() {} + + bool OnChange(UICheckBox::UICheckBoxState state) override + { + int16_t xPos = uiView_->GetX(); + int16_t yPos = uiView_->GetY(); + uiView_->Invalidate(); + xPos += 10; // 10: increase xPos + yPos += 10; // 10: increase yPos + + uiView_->SetX(xPos); + uiView_->SetY(yPos); + uiView_->Invalidate(); + return true; + } + +private: + UIView* uiView_; +}; + +void UITestBUTTON::UIKit_Toggle_Button_Test_001() const +{ + if (container_ != nullptr) { + UILabel* label = new UILabel(); + container_->Add(label); + // 0:x-coordinate, 270:y-coordinate, 20:new height + label->SetPosition(TEXT_DISTANCE_TO_LEFT_SIDE, 270, Screen::GetInstance().GetWidth(), + TITLE_LABEL_DEFAULT_HEIGHT); + label->SetText("togglebutton功能"); + label->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); + + UIToggleButton* togglebutton = new UIToggleButton(); + togglebutton->SetPosition(20, 300); // 20: x-coordinate, 300: y-coordinate + togglebutton->SetStyle(STYLE_BACKGROUND_OPA, 0); // 0: opacity + togglebutton->SetState(false); + + UIToggleButton* togglebutton2 = new UIToggleButton(); + togglebutton2->SetPosition(100, 300); // 100: x-coordinate, 300: y-coordinate + togglebutton2->SetStyle(STYLE_BACKGROUND_OPA, 0); // 0: opacity + togglebutton2->SetState(false); + togglebutton2->SetWidth(60); // 60: width + togglebutton2->SetHeight(40); // 40: height + + UIToggleButton* togglebutton3 = new UIToggleButton(); + togglebutton3->SetPosition(190, 300); // 190: x-coordinate, 300: y-coordinate + togglebutton3->SetStyle(STYLE_BACKGROUND_OPA, 0); // 0: opacity + togglebutton3->SetState(false); + togglebutton3->SetWidth(50); // 50: width + togglebutton3->SetHeight(70); // 70: height + + UIToggleButton* togglebutton4 = new UIToggleButton(); + + UICheckBox::OnChangeListener* ChangeListener = + new TestBtnOnStateChangeListener(reinterpret_cast(togglebutton4)); + togglebutton4->SetOnChangeListener(ChangeListener); + + togglebutton4->SetPosition(250, 300); // 250: x-coordinate, 300: y-coordinate + togglebutton4->SetStyle(STYLE_BACKGROUND_OPA, 0); // 0: opacity + togglebutton4->SetState(false); + togglebutton4->SetWidth(80); // 80: width + togglebutton4->SetHeight(80); // 80: height + togglebutton4->SetState(true); + + UIToggleButton* togglebutton5 = new UIToggleButton(); + togglebutton5->SetPosition(340, 300); // 340: x-coordinate, 300: y-coordinate + togglebutton5->SetWidth(-1); // -1: width + togglebutton5->SetHeight(90); // 90: width + + UIToggleButton* togglebutton6 = new UIToggleButton(); + togglebutton6->SetPosition(350, 300); // 350: x-coordinate, 300: y-coordinate + togglebutton6->SetWidth(0); // 0: width + togglebutton6->SetHeight(0); // 0: width + + UIToggleButton* togglebutton7 = new UIToggleButton(); + togglebutton7->SetPosition(360, 300); // 360: x-coordinate, 300: y-coordinate + togglebutton7->SetWidth(1000); // 1000: width + togglebutton7->SetHeight(50); // 50: width + + container_->Add(togglebutton); + container_->Add(togglebutton2); + container_->Add(togglebutton3); + container_->Add(togglebutton4); + container_->Add(togglebutton5); + container_->Add(togglebutton6); + container_->Add(togglebutton7); + } +} +void UITestBUTTON::UIKit_Check_Box_Test_002() const +{ + if (container_ != nullptr) { + UILabel* label = new UILabel(); + container_->Add(label); + // 0:x-coordinate, 400:y-coordinate, 20:new height + label->SetPosition(TEXT_DISTANCE_TO_LEFT_SIDE, 400, Screen::GetInstance().GetWidth(), + TITLE_LABEL_DEFAULT_HEIGHT); + label->SetText("checkbox SetImage功能"); + label->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); + + UICheckBox* checkbox = new UICheckBox(); + checkbox->SetPosition(30, 430); // 30: x-coordinate, 430: y-coordinate + checkbox->SetWidth(130); // 130: width + checkbox->SetHeight(130); // 130: height + checkbox->SetImages(BLUE_IMAGE_PATH, YELLOW_IMAGE_PATH); + + UICheckBox* checkbox2 = new UICheckBox(); + checkbox2->SetPosition(200, 430); // 200: x-coordinate, 430: y-coordinate + checkbox2->SetWidth(130); // 130: width + checkbox2->SetHeight(130); // 130: height + checkbox2->SetImages(GREEN_IMAGE_PATH, RED_IMAGE_PATH); + + container_->Add(checkbox); + container_->Add(checkbox2); + } +} + +void UITestBUTTON::UIKit_Radio_Button_Test_002() const +{ + if (container_ != nullptr) { + UILabel* label = new UILabel(); + container_->Add(label); + // 0:x-coordinate, 570:y-coordinate, 20:new height + label->SetPosition(TEXT_DISTANCE_TO_LEFT_SIDE, 570, Screen::GetInstance().GetWidth(), + TITLE_LABEL_DEFAULT_HEIGHT); + label->SetText("radiobutton SetImage功能"); + label->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); + + UIRadioButton* radioButton = new UIRadioButton("aaa"); + radioButton->SetPosition(30, 10); // 30: x-coordinate, 10: y-coordinate + radioButton->SetWidth(130); // 130: width + radioButton->SetHeight(130); // 130: height + radioButton->SetImages(BLUE_IMAGE_PATH, YELLOW_IMAGE_PATH); + + UIRadioButton* radioButton2 = new UIRadioButton("aaa"); + radioButton2->SetPosition(200, 10); // 200: x-coordinate, 10: y-coordinate + radioButton2->SetWidth(130); // 130: width + radioButton2->SetHeight(130); // 130: height + radioButton2->SetImages(GREEN_IMAGE_PATH, RED_IMAGE_PATH); + + OHOS::UIViewGroup* viewGroup = new UIViewGroup(); + viewGroup->SetPosition(0, 600); // 0: x-coordinate, 600: y-coordinate + viewGroup->SetWidth(Screen::GetInstance().GetWidth()); // 2: half width + viewGroup->SetHeight(Screen::GetInstance().GetHeight() / 2); // 2: half height + + viewGroup->Add(radioButton); + viewGroup->Add(radioButton2); + viewGroup->SetStyle(STYLE_BACKGROUND_OPA, 0); + + container_->Add(viewGroup); + } +} + +void UITestBUTTON::UIKit_Toggle_Button_Test_002() const +{ + if (container_ != nullptr) { + UILabel* label = new UILabel(); + container_->Add(label); + // 0:x-coordinate, 740:y-coordinate, 20:new height + label->SetPosition(TEXT_DISTANCE_TO_LEFT_SIDE, 740, Screen::GetInstance().GetWidth(), + TITLE_LABEL_DEFAULT_HEIGHT); + label->SetText("togglebutton SetImage功能"); + label->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); + + UIToggleButton* togglebutton = new UIToggleButton(); + togglebutton->SetPosition(30, 770); // 30: x-coordinate, 770: y-coordinate + togglebutton->SetStyle(STYLE_BACKGROUND_OPA, 0); // 0: opacity + togglebutton->SetState(true); + togglebutton->SetWidth(130); // 130: width + togglebutton->SetHeight(130); // 130: height + togglebutton->SetImages(BLUE_IMAGE_PATH, YELLOW_IMAGE_PATH); + + UIToggleButton* togglebutton2 = new UIToggleButton(); + UICheckBox::OnChangeListener* ChangeListener = + new TestBtnOnStateChangeListener(reinterpret_cast(togglebutton2)); + togglebutton2->SetOnChangeListener(ChangeListener); + togglebutton2->SetPosition(200, 770); // 200: x-coordinate, 770: y-coordinate + togglebutton2->SetStyle(STYLE_BACKGROUND_OPA, 0); // 0: opacity + togglebutton2->SetState(false); + togglebutton2->SetWidth(130); // 130: width + togglebutton2->SetHeight(130); // 130: height + togglebutton2->SetImages(GREEN_IMAGE_PATH, RED_IMAGE_PATH); + + container_->Add(togglebutton); + container_->Add(togglebutton2); + } +} + +class TestBtnOnClickShapeChangeListener : public UIView::OnClickListener { +public: + TestBtnOnClickShapeChangeListener(UIView* uiView, int16_t grid) : uiView_(uiView), changeGrid_(grid) {} + + ~TestBtnOnClickShapeChangeListener() {} + + bool OnClick(UIView& view, const ClickEvent& event) override + { + int16_t width = uiView_->GetWidth() + changeGrid_; + int16_t height = uiView_->GetHeight() + changeGrid_; + if (changeGrid_ < 0) { + uiView_->Invalidate(); + } + uiView_->Resize(width, height); + uiView_->Invalidate(); + return true; + } + +private: + UIView* uiView_; + int16_t changeGrid_; +}; + +class TestBtnOnClickPositionChangeListener : public OHOS::UIView::OnClickListener { +public: + enum class MoveType { + MOVE_LEFT, + MOVE_RIGHT, + MOVE_TOP, + MOVE_BOTTOM, + }; + TestBtnOnClickPositionChangeListener(UIView* uiView, MoveType moveType, uint16_t grid) + : uiView_(uiView), moveType_(moveType), grid_(grid) + { + } + + ~TestBtnOnClickPositionChangeListener() {} + + bool OnClick(UIView& view, const ClickEvent& event) override + { + int16_t xPos = uiView_->GetX(); + int16_t yPos = uiView_->GetY(); + uiView_->Invalidate(); + if (moveType_ == MoveType::MOVE_LEFT) { + xPos = xPos - grid_; + } else if (moveType_ == MoveType::MOVE_RIGHT) { + xPos = xPos + grid_; + } else if (moveType_ == MoveType::MOVE_TOP) { + yPos = yPos - grid_; + } else if (moveType_ == MoveType::MOVE_BOTTOM) { + yPos = yPos + grid_; + } + uiView_->SetX(xPos); + uiView_->SetY(yPos); + uiView_->Invalidate(); + return true; + } + +private: + UIView* uiView_; + MoveType moveType_; + uint16_t grid_; +}; + +class TestBtnOnClickVisableListener : public OHOS::UIView::OnClickListener { +public: + TestBtnOnClickVisableListener(UIView* uiView, bool visible) : uiView_(uiView), visible_(visible) {} + + ~TestBtnOnClickVisableListener() {} + + bool OnClick(UIView& view, const ClickEvent& event) override + { + uiView_->SetVisible(visible_); + uiView_->Invalidate(); + return true; + } + +private: + UIView* uiView_; + bool visible_; +}; + +class TestBtnOnClickTouchableListener : public UIView::OnClickListener { +public: + TestBtnOnClickTouchableListener(UIView* uiView, bool touchable) : uiView_(uiView), touchable_(touchable) {} + + ~TestBtnOnClickTouchableListener() {} + + bool OnClick(UIView& view, const ClickEvent& event) override + { + uiView_->SetTouchable(touchable_); + uiView_->Invalidate(); + return true; + } + +private: + UIView* uiView_; + bool touchable_; +}; + +class TestBtnOnClickChangeColorListener : public OHOS::UIView::OnClickListener { +public: + TestBtnOnClickChangeColorListener(UIView* uiView, uint16_t red, uint16_t green, uint16_t blue) + : uiView_(uiView), red_(red), green_(green), blue_(blue) + { + } + + ~TestBtnOnClickChangeColorListener() {} + + bool OnClick(UIView& view, const ClickEvent& event) override + { + ColorType color; + color.full = uiView_->GetStyle(STYLE_BACKGROUND_COLOR); + color.red = red_; + color.green = green_; + color.blue = blue_; + uiView_->SetStyle(STYLE_BACKGROUND_COLOR, color.full); + uiView_->Invalidate(); + return true; + } + +private: + UIView* uiView_; + uint16_t red_; + uint16_t green_; + uint16_t blue_; +}; + +class TestBtnOnClickRevertColorListener : public UIView::OnClickListener { +public: + explicit TestBtnOnClickRevertColorListener(UIView* uiView) : uiView_(uiView), originColor_(0) + { + if (uiView != nullptr) { + originColor_ = uiView->GetStyle(STYLE_BACKGROUND_COLOR); + } + } + + ~TestBtnOnClickRevertColorListener() {} + + bool OnClick(UIView& view, const ClickEvent& event) override + { + uiView_->SetStyle(STYLE_BACKGROUND_COLOR, originColor_); + uiView_->Invalidate(); + return true; + } + +private: + UIView* uiView_; + uint32_t originColor_; +}; + +class TestBtnOnClickRevertToOriginStateListener : public UIView::OnClickListener { +public: + explicit TestBtnOnClickRevertToOriginStateListener(UIView* uiView) : uiView_(uiView), originColor_(0), + width_(0), height_(0), visible_(false), + touchable_(false) + { + if (uiView != nullptr) { + originColor_ = uiView->GetStyle(STYLE_BACKGROUND_COLOR); + width_ = uiView->GetWidth(); + height_ = uiView->GetHeight(); + visible_ = uiView->IsVisible(); + touchable_ = uiView->IsTouchable(); + } + } + + ~TestBtnOnClickRevertToOriginStateListener() {} + + bool OnClick(UIView& view, const ClickEvent& event) override + { + uiView_->Invalidate(); + uiView_->SetStyle(STYLE_BACKGROUND_COLOR, originColor_); + uiView_->SetWidth(width_); + uiView_->SetHeight(height_); + uiView_->SetVisible(visible_); + uiView_->SetTouchable(touchable_); + ((UIButton*)uiView_)->Invalidate(); + return true; + } + +private: + UIView* uiView_; + uint32_t originColor_; + uint32_t width_; + uint32_t height_; + bool visible_; + bool touchable_; +}; + +UILabel* GetTestUILabel(const char* titlename) +{ + if (titlename == nullptr) { + return nullptr; + } + + UILabel* label = new UILabel(); + // 900:y-coordinate + label->SetPosition(TEXT_DISTANCE_TO_LEFT_SIDE, 900, Screen::GetInstance().GetWidth(), TITLE_LABEL_DEFAULT_HEIGHT); + label->SetText(titlename); + label->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); + return label; +} + +UILabelButton* GetTestUIButton(const char* buttonText, int16_t x, int16_t y, UIButton* button) +{ + if (buttonText == nullptr) { + return nullptr; + } + + UILabelButton* labelButton = new UILabelButton(); + // 150: x-coordinate, 440: y-coordinate + labelButton->SetPosition(x, y); + labelButton->Resize(BUTTON_WIDHT1, BUTTON_HEIGHT1); + labelButton->SetText(buttonText); + labelButton->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); + labelButton->SetStyleForState(STYLE_BORDER_RADIUS, BUTTON_STYLE_BORDER_RADIUS_VALUE, UIButton::PRESSED); + labelButton->SetStyleForState(STYLE_BORDER_RADIUS, BUTTON_STYLE_BORDER_RADIUS_VALUE, UIButton::INACTIVE); + labelButton->SetStyleForState(STYLE_BACKGROUND_COLOR, BUTTON_STYLE_BACKGROUND_COLOR_VALUE, UIButton::RELEASED); + labelButton->SetStyleForState(STYLE_BACKGROUND_COLOR, BUTTON_STYLE_BACKGROUND_COLOR_VALUE, UIButton::PRESSED); + labelButton->SetStyleForState(STYLE_BACKGROUND_COLOR, BUTTON_STYLE_BACKGROUND_COLOR_VALUE, UIButton::INACTIVE); + return labelButton; +} + +void UIKit_BUTTON_TEST_002(UIScrollView* container, UIButton* button) +{ + if ((container == nullptr) || (button == nullptr)) { + return; + } + UILabelButton* button8 = GetTestUIButton("隐藏", 430, 940, button); // 430: x-coordinate, 940: y-coordinate + UIView::OnClickListener* clickEnableVisiableListener = new TestBtnOnClickVisableListener((UIView*)button, false); + button8->SetOnClickListener(clickEnableVisiableListener); + + UILabelButton* button9 = GetTestUIButton("显示", 430, 990, button); // 430: x-coordinate, 990: y-coordinate + UIView::OnClickListener* clickDisableVisiableListener = new TestBtnOnClickVisableListener((UIView*)button, true); + button9->SetOnClickListener(clickDisableVisiableListener); + + UILabelButton* button10 = GetTestUIButton("可触摸 ", 520, 940, button); // 520: x-coordinate, 940: y-coordinate + UIView::OnClickListener* clickEnableTouchableListener = new TestBtnOnClickTouchableListener((UIView*)button, true); + button10->SetOnClickListener(clickEnableTouchableListener); + + UILabelButton* button11 = GetTestUIButton("不可触摸", 520, 990, button); // 520: x-coordinate, 990: y-coordinate + UIView::OnClickListener* clickDisableTouchableListener = + new TestBtnOnClickTouchableListener((UIView*)button, false); + button11->SetOnClickListener(clickDisableTouchableListener); + + UILabelButton* button12 = GetTestUIButton("变白", 160, 1040, button); // 160: x-coordinate, 1040: y-coordinate + UIView::OnClickListener* clickColorToWhiteListener = + new TestBtnOnClickChangeColorListener((UIView*)button, 0xFF, 0xFF, 0xFF); + button12->SetOnClickListener(clickColorToWhiteListener); + + UILabelButton* button13 = GetTestUIButton("变红", 160, 1090, button); // 160: x-coordinate, 1090: y-coordinate + UIView::OnClickListener* clickColorToRedListener = + new TestBtnOnClickChangeColorListener((UIView*)button, 0xFF, 0, 0); + button13->SetOnClickListener(clickColorToRedListener); + + UILabelButton* button14 = GetTestUIButton("色彩还原", 250, 1040, button); // 250: x-coordinate, 1040: y-coordinate + UIView::OnClickListener* clickRevetColorListener = new TestBtnOnClickRevertColorListener((UIView*)button); + button14->SetOnClickListener(clickRevetColorListener); + + UILabelButton* button15 = GetTestUIButton("全部还原", 250, 1090, button); // 250: x-coordinate, 1090: y-coordinate + UIView::OnClickListener* clickRevetToOriginListener = + new TestBtnOnClickRevertToOriginStateListener((UIView*)button); + button15->SetOnClickListener(clickRevetToOriginListener); + + container->Add(button8); + container->Add(button9); + container->Add(button10); + container->Add(button11); + container->Add(button12); + container->Add(button13); + container->Add(button14); + container->Add(button15); +} + +void UITestBUTTON::UIKit_Button_Test_001() const +{ + if (container_ != nullptr) { + UILabel* label = GetTestUILabel("普通button功能效果"); + container_->Add(label); + + UIButton* button = new UIButton(); + button->SetPosition(10, 935); // 10: x-coordinate, 935: y-coordinate + button->SetWidth(80); // 80: width + button->SetHeight(60); // 60: height + button->SetImageSrc(BLUE_IMAGE_PATH, YELLOW_IMAGE_PATH); + + UILabelButton* button2 = GetTestUIButton("放大", 160, 940, button); // 160: x-coordinate, 940: y-coordinate + UIView::OnClickListener* clickBigListener = new TestBtnOnClickShapeChangeListener(button, CHANGE_SIZE); + button2->SetOnClickListener(clickBigListener); + + UILabelButton* button3 = GetTestUIButton("缩小", 160, 990, button); // 160: x-coordinate, 990: y-coordinate + UIView::OnClickListener* clickSmallListener = new TestBtnOnClickShapeChangeListener(button, -CHANGE_SIZE); + button3->SetOnClickListener(clickSmallListener); + + UILabelButton* button4 = GetTestUIButton("左移", 250, 940, button); // 250: x-coordinate, 940: y-coordinate + UIView::OnClickListener* clickLeftListener = new TestBtnOnClickPositionChangeListener( + (UIView*)button, TestBtnOnClickPositionChangeListener::MoveType::MOVE_LEFT, CHANGE_SIZE); + button4->SetOnClickListener(clickLeftListener); + + UILabelButton* button5 = GetTestUIButton("右移", 250, 990, button); // 250: x-coordinate, 990: y-coordinate + button5->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); + UIView::OnClickListener* clickRightListener = new TestBtnOnClickPositionChangeListener( + (UIView*)button, TestBtnOnClickPositionChangeListener::MoveType::MOVE_RIGHT, CHANGE_SIZE); + button5->SetOnClickListener(clickRightListener); + + UILabelButton* button6 = GetTestUIButton("上移", 340, 940, button); // 340: x-coordinate, 940: y-coordinate + button6->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); + UIView::OnClickListener* clickUpListener = new TestBtnOnClickPositionChangeListener( + (UIView*)button, TestBtnOnClickPositionChangeListener::MoveType::MOVE_TOP, CHANGE_SIZE); + button6->SetOnClickListener(clickUpListener); + + UILabelButton* button7 = GetTestUIButton("下移", 340, 990, button); // 340: x-coordinate, 990: y-coordinate + UIView::OnClickListener* clickDownListener = new TestBtnOnClickPositionChangeListener( + (UIView*)button, TestBtnOnClickPositionChangeListener::MoveType::MOVE_BOTTOM, CHANGE_SIZE); + button7->SetOnClickListener(clickDownListener); + + container_->Add(button); + container_->Add(button2); + container_->Add(button3); + container_->Add(button4); + container_->Add(button5); + container_->Add(button6); + container_->Add(button7); + + UIKit_BUTTON_TEST_002(container_, button); + } +} +} // namespace OHOS \ No newline at end of file diff --git a/test/uitest/test_button/ui_test_button.h b/test/uitest/test_button/ui_test_button.h new file mode 100755 index 0000000..b6d1000 --- /dev/null +++ b/test/uitest/test_button/ui_test_button.h @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef UI_TEST_BUTTON_H +#define UI_TEST_BUTTON_H + +#include "components/ui_scroll_view.h" +#include "ui_test.h" + +namespace OHOS { +class UITestBUTTON : public UITest { +public: + UITestBUTTON() {} + ~UITestBUTTON() {} + void SetUp() override; + void TearDown() override; + UIView* GetTestView() override; + + /** + * @brief Test Checkbox Function + */ + void UIKit_Check_Box_Test_001() const; + + /** + * @brief Test Checkbox's SetImage Function + */ + void UIKit_Check_Box_Test_002() const; + + /** + * @brief Test Radiobutton Function + */ + void UIKit_Radio_Button_Test_001() const; + + /** + * @brief Test Radiobutton's SetImage Function + */ + void UIKit_Radio_Button_Test_002() const; + + /** + * @brief Test Togglebutton Function + */ + void UIKit_Toggle_Button_Test_001() const; + + /** + * @brief Test Togglebutton's SetImage Function + */ + void UIKit_Toggle_Button_Test_002() const; + + /** + * @brief Test button Function + */ + void UIKit_Button_Test_001() const; + +private: + static constexpr int16_t CHANGE_SIZE = 10; + UIScrollView* container_ = nullptr; +}; +} // namespace OHOS +#endif // UI_TEST_BUTTON_H diff --git a/test/uitest/test_canvas/ui_test_canvas.cpp b/test/uitest/test_canvas/ui_test_canvas.cpp new file mode 100755 index 0000000..5b13ad7 --- /dev/null +++ b/test/uitest/test_canvas/ui_test_canvas.cpp @@ -0,0 +1,927 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "ui_test_canvas.h" +#include "common/screen.h" +#include "components/ui_label.h" +#include "test_resource_config.h" + +namespace OHOS { +void UITestCanvas::SetUp() +{ + if (container_ == nullptr) { + container_ = new UIScrollView(); + container_->Resize(Screen::GetInstance().GetWidth(), Screen::GetInstance().GetHeight() - BACK_BUTTON_HEIGHT); + container_->SetHorizontalScrollState(false); + container_->SetThrowDrag(true); + } + positionY_ = 0; +} + +void UITestCanvas::TearDown() +{ + DeleteChildren(container_); + container_ = nullptr; +} + +UIView* UITestCanvas::GetTestView() +{ + UIKitCanvasTestDrawLine001(); + UIKitCanvasTestDrawLine002(); + UIKitCanvasTestDrawCurve001(); + UIKitCanvasTestDrawCurve002(); + UIKitCanvasTestDrawRect001(); + UIKitCanvasTestDrawRect002(); + UIKitCanvasTestDrawRect003(); + UIKitCanvasTestDrawCircle001(); + UIKitCanvasTestDrawCircle002(); + UIKitCanvasTestDrawCircle003(); + UIKitCanvasTestDrawArc001(); + UIKitCanvasTestDrawImage001(); + UIKitCanvasTestDrawLabel001(); + UIKitCanvasTestDrawSector001(); + UIKitCanvasTestClear001(); + UIKitCanvasTestDrawPath001(); + UIKitCanvasTestDrawPath002(); + UIKitCanvasTestDrawPath003(); + UIKitCanvasTestDrawPath004(); + UIKitCanvasTestDrawPath005(); + UIKitCanvasTestDrawPath006(); + UIKitCanvasTestDrawPath007(); + UIKitCanvasTestDrawPath008(); + UIKitCanvasTestDrawPath009(); + UIKitCanvasTestDrawPath010(); + UIKitCanvasTestDrawPath011(); + UIKitCanvasTestDrawPath012(); + UIKitCanvasTestDrawPath013(); + UIKitCanvasTestDrawPath014(); + UIKitCanvasTestDrawPath015(); + UIKitCanvasTestDrawPath016(); + UIKitCanvasTestDrawPath017(); + UIKitCanvasTestDrawPath018(); + UIKitCanvasTestDrawPath019(); + UIKitCanvasTestDrawPath020(); + UIKitCanvasTestDrawPath021(); + UIKitCanvasTestDrawPath022(); + UIKitCanvasTestDrawPath023(); + UIKitCanvasTestDrawPath024(); + UIKitCanvasTestDrawPath025(); + UIKitCanvasTestDrawPath026(); + UIKitCanvasTestDrawPath027(); + UIKitCanvasTestDrawPath028(); + UIKitCanvasTestDrawPath029(); + UIKitCanvasTestDrawPath030(); + UIKitCanvasTestDrawPath031(); + UIKitCanvasTestDrawPath032(); + UIKitCanvasTestDrawPath033(); + UIKitCanvasTestDrawPath034(); + + return container_; +} + +void UITestCanvas::CreateTitleLabel(const char* title) +{ + UILabel* titleLabel = new UILabel(); + titleLabel->SetPosition(TEXT_DISTANCE_TO_LEFT_SIDE, positionY_, Screen::GetInstance().GetWidth(), TITLE_HEIGHT); + titleLabel->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); + titleLabel->SetText(title); + container_->Add(titleLabel); + positionY_ += TITLE_HEIGHT + 8; // 8: gap +} + +UICanvas* UITestCanvas::CreateCanvas() +{ + UICanvas* canvas = new UICanvas(); + canvas->SetHeight(CANVAS_HEIGHT); + canvas->SetWidth(CANVAS_WIDTH); + canvas->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE, positionY_); + canvas->SetStyle(STYLE_BACKGROUND_COLOR, Color::Gray().full); + container_->Add(canvas); + positionY_ += CANVAS_HEIGHT + GAP; + return canvas; +} + +void UITestCanvas::UIKitCanvasTestDrawLine001() +{ + if (container_ == nullptr) { + return; + } + CreateTitleLabel("绘制直线"); + UICanvas* canvas = CreateCanvas(); + Paint paint; + // {0, 10}: Start point coordinates x, y; {50, 10}: end point coordinates x, y + canvas->DrawLine({0, 10}, {50, 10}, paint); +} + +void UITestCanvas::UIKitCanvasTestDrawLine002() +{ + if (container_ == nullptr) { + return; + } + CreateTitleLabel("绘制直线"); + UICanvas* canvas = CreateCanvas(); + + Paint paint; + paint.SetStrokeWidth(5); // 5: line width + canvas->SetStartPosition({ 50, 10 }); // {50, 10}: Start point coordinates x, y; + canvas->DrawLine({ 100, 50 }, paint); // {100, 50}: end point coordinates x, y +} + +void UITestCanvas::UIKitCanvasTestDrawCurve001() +{ + if (container_ == nullptr) { + return; + } + CreateTitleLabel("绘制曲线"); + UICanvas* canvas = CreateCanvas(); + + Paint paint; + paint.SetStrokeColor(Color::Red()); + canvas->DrawCurve({ 100, 50 }, { 150, 50 }, { 150, 50 }, { 150, 100 }, paint); +} + +void UITestCanvas::UIKitCanvasTestDrawCurve002() +{ + if (container_ == nullptr) { + return; + } + CreateTitleLabel("绘制曲线"); + UICanvas* canvas = CreateCanvas(); + + Paint paint; + paint.SetStrokeColor(Color::Red()); + canvas->DrawCurve({ 100, 50 }, { 150, 50 }, { 150, 100 }, paint); +} + +void UITestCanvas::UIKitCanvasTestDrawRect001() +{ + if (container_ == nullptr) { + return; + } + CreateTitleLabel("矩形填充"); + UICanvas* canvas = CreateCanvas(); + + Paint paint; + paint.SetStyle(Paint::PaintStyle::FILL_STYLE); + paint.SetFillColor(Color::Yellow()); + paint.SetStrokeWidth(30); // 30: line width + // {100, 10}: left corner coordinates point, 50: width, 50: rectangle style + canvas->DrawRect({ 100, 10 }, 50, 50, paint); +} + +void UITestCanvas::UIKitCanvasTestDrawRect002() +{ + if (container_ == nullptr) { + return; + } + CreateTitleLabel("矩形描边"); + UICanvas* canvas = CreateCanvas(); + + Paint paint; + paint.SetStyle(Paint::PaintStyle::STROKE_STYLE); + paint.SetStrokeColor(Color::Blue()); + // {200, 10}: left corner coordinates point, 50: width, 50: rectangle style + canvas->DrawRect({ 200, 10 }, 50, 50, paint); +} + +void UITestCanvas::UIKitCanvasTestDrawRect003() +{ + if (container_ == nullptr) { + return; + } + CreateTitleLabel("矩形填充 + 描边"); + UICanvas* canvas = CreateCanvas(); + + Paint paint; + paint.SetStyle(Paint::PaintStyle::STROKE_FILL_STYLE); + paint.SetFillColor(Color::Yellow()); + paint.SetStrokeColor(Color::Blue()); + // {300, 10}: left corner coordinates point, 50: width, 50: rectangle style + canvas->DrawRect({ 300, 10 }, 50, 50, paint); +} + +void UITestCanvas::UIKitCanvasTestDrawCircle001() +{ + if (container_ == nullptr) { + return; + } + CreateTitleLabel("圆形填充"); + UICanvas* canvas = CreateCanvas(); + + Paint paint; + paint.SetStyle(Paint::PaintStyle::FILL_STYLE); + paint.SetStrokeColor(Color::Yellow()); + paint.SetFillColor(Color::Yellow()); + paint.SetStrokeWidth(10); // 10: line width + paint.SetOpacity(127); // 127: opacity + // {100, 100}: circle center coordinates, 30: circle radius + canvas->DrawCircle({ 100, 100 }, 30, paint); +} + +void UITestCanvas::UIKitCanvasTestDrawCircle002() +{ + if (container_ == nullptr) { + return; + } + CreateTitleLabel("圆形描边"); + UICanvas* canvas = CreateCanvas(); + + Paint paint; + paint.SetStyle(Paint::PaintStyle::STROKE_STYLE); + paint.SetStrokeColor(Color::Blue()); + paint.SetStrokeWidth(10); // 10: line width + paint.SetOpacity(127); // 127: opacity + // {200, 100}: circle center coordinates, 30: circle radius + canvas->DrawCircle({ 200, 100 }, 30, paint); +} + +void UITestCanvas::UIKitCanvasTestDrawCircle003() +{ + if (container_ == nullptr) { + return; + } + CreateTitleLabel("圆形填充 + 描边"); + UICanvas* canvas = CreateCanvas(); + + Paint paint; + paint.SetStyle(Paint::PaintStyle::STROKE_FILL_STYLE); + paint.SetFillColor(Color::Yellow()); + paint.SetStrokeColor(Color::Blue()); + paint.SetStrokeWidth(10); // 10: line width + paint.SetOpacity(127); // 127: opacity + // {300, 100}: circle center coordinates, 30: circle radius + canvas->DrawCircle({ 300, 100 }, 30, paint); +} + +void UITestCanvas::UIKitCanvasTestDrawArc001() +{ + if (container_ == nullptr) { + return; + } + CreateTitleLabel("绘制弧线"); + UICanvas* canvas = CreateCanvas(); + + Paint paint; + paint.SetStyle(Paint::PaintStyle::STROKE_STYLE); + paint.SetStrokeColor(Color::Red()); + paint.SetStrokeWidth(10); // 10: line width + // {100, 150}: arc's center coordinates, 50: arc radius, 135: start angle, 270: end angle + canvas->DrawArc({ 100, 150 }, 50, 135, 270, paint); +} + +void UITestCanvas::UIKitCanvasTestDrawImage001() +{ + if (container_ == nullptr) { + return; + } + CreateTitleLabel("绘制图片"); + UICanvas* canvas = CreateCanvas(); + + Paint paint; + paint.SetOpacity(127); // 127: opacity + // {200, 50}: start point coordinates + canvas->DrawImage({ 200, 50 }, GREEN_IMAGE_PATH, paint); +} + +void UITestCanvas::UIKitCanvasTestDrawLabel001() +{ + if (container_ == nullptr) { + return; + } + CreateTitleLabel("绘制文字"); + UICanvas* canvas = CreateCanvas(); + + Paint paint; + paint.SetFillColor(Color::Blue()); + UICanvas::FontStyle fontStyle; + fontStyle.align = TEXT_ALIGNMENT_RIGHT; + fontStyle.direct = TEXT_DIRECT_RTL; + fontStyle.fontName = DEFAULT_VECTOR_FONT_FILENAME; + fontStyle.fontSize = 30; // 30: font size + fontStyle.letterSpace = 10; // 10 letter space + // {50, 50}: start point coordinates, 100: max width + canvas->DrawLabel({ 50, 50 }, "canvas绘制字体", 100, fontStyle, paint); +} + +void UITestCanvas::UIKitCanvasTestDrawSector001() +{ + if (container_ == nullptr) { + return; + } + CreateTitleLabel("扇形填充"); + UICanvas* canvas = CreateCanvas(); + + Paint paint; + paint.SetStyle(Paint::PaintStyle::FILL_STYLE); + paint.SetFillColor(Color::Yellow()); + // {350, 150}: sector's center coordinates, 100: sector radius, 0: start angle, 30: end angle + canvas->DrawSector({ 350, 150 }, 100, 0, 30, paint); +} + +void UITestCanvas::UIKitCanvasTestClear001() +{ + if (container_ == nullptr) { + return; + } + CreateTitleLabel("清空画布,无显示"); + UICanvas* canvas = CreateCanvas(); + + Paint paint; + // {0, 10}: Start point coordinates x, y; {50, 10}: end point coordinates x, y + canvas->DrawLine({ 0, 10 }, { 50, 10 }, paint); + canvas->Clear(); +} + +void UITestCanvas::UIKitCanvasTestDrawPath001() +{ + if (container_ == nullptr) { + return; + } + CreateTitleLabel("moveTo,无显示"); + UICanvas* canvas = CreateCanvas(); + + Paint paint; + canvas->BeginPath(); + canvas->MoveTo({ START1_X, START1_Y }); + canvas->ClosePath(); + canvas->DrawPath(paint); +} + +void UITestCanvas::UIKitCanvasTestDrawPath002() +{ + if (container_ == nullptr) { + return; + } + CreateTitleLabel("lineTo,无显示"); + UICanvas* canvas = CreateCanvas(); + + Paint paint; + canvas->BeginPath(); + canvas->LineTo({ LINE1_X, LINE1_Y }); + canvas->DrawPath(paint); +} + +void UITestCanvas::UIKitCanvasTestDrawPath003() +{ + if (container_ == nullptr) { + return; + } + CreateTitleLabel("arc"); + UICanvas* canvas = CreateCanvas(); + + Paint paint; + canvas->BeginPath(); + canvas->ArcTo({ CENTER_X, CENTER_Y }, RADIUS, START_ANGLE, END_ANGLE); + canvas->DrawPath(paint); +} + +void UITestCanvas::UIKitCanvasTestDrawPath004() +{ + if (container_ == nullptr) { + return; + } + CreateTitleLabel("rect"); + UICanvas* canvas = CreateCanvas(); + + Paint paint; + canvas->BeginPath(); + canvas->AddRect({ RECT_X, RECT_Y }, RECT_HEIGHT, RECT_WIDTH); + canvas->DrawPath(paint); +} + +void UITestCanvas::UIKitCanvasTestDrawPath005() +{ + if (container_ == nullptr) { + return; + } + CreateTitleLabel("closePath,无显示"); + UICanvas* canvas = CreateCanvas(); + + Paint paint; + canvas->BeginPath(); + canvas->ClosePath(); + canvas->DrawPath(paint); +} + +void UITestCanvas::UIKitCanvasTestDrawPath006() +{ + if (container_ == nullptr) { + return; + } + CreateTitleLabel("moveTo + lineTo"); + UICanvas* canvas = CreateCanvas(); + + Paint paint; + canvas->BeginPath(); + canvas->MoveTo({ START1_X, START1_Y }); + canvas->LineTo({ LINE1_X, LINE1_Y }); + canvas->DrawPath(paint); +} + +void UITestCanvas::UIKitCanvasTestDrawPath007() +{ + if (container_ == nullptr) { + return; + } + CreateTitleLabel("moveTo + arc"); + UICanvas* canvas = CreateCanvas(); + + Paint paint; + canvas->BeginPath(); + canvas->MoveTo({ START1_X, START1_Y }); + canvas->ArcTo({ CENTER_X, CENTER_Y }, RADIUS, START_ANGLE, END_ANGLE); + canvas->DrawPath(paint); +} + +void UITestCanvas::UIKitCanvasTestDrawPath008() +{ + if (container_ == nullptr) { + return; + } + CreateTitleLabel("moveTo + rect"); + UICanvas* canvas = CreateCanvas(); + + Paint paint; + canvas->BeginPath(); + canvas->MoveTo({ START1_X, START1_Y }); + canvas->AddRect({ RECT_X, RECT_Y }, RECT_HEIGHT, RECT_WIDTH); + canvas->DrawPath(paint); +} + +void UITestCanvas::UIKitCanvasTestDrawPath009() +{ + if (container_ == nullptr) { + return; + } + CreateTitleLabel("moveTo + closePath"); + UICanvas* canvas = CreateCanvas(); + + Paint paint; + canvas->BeginPath(); + canvas->MoveTo({ START1_X, START1_Y }); + canvas->LineTo({ LINE1_X, LINE1_Y }); + canvas->LineTo({ LINE2_X, LINE2_Y }); + canvas->ClosePath(); + canvas->DrawPath(paint); +} + +void UITestCanvas::UIKitCanvasTestDrawPath010() +{ + if (container_ == nullptr) { + return; + } + CreateTitleLabel("闭合路径调用closePath"); + UICanvas* canvas = CreateCanvas(); + + Paint paint; + canvas->BeginPath(); + canvas->MoveTo({ START1_X, START1_Y }); + canvas->LineTo({ LINE1_X, LINE1_Y }); + canvas->LineTo({ LINE2_X, LINE2_Y }); + canvas->LineTo({ START1_X, START1_Y }); + canvas->ClosePath(); + canvas->DrawPath(paint); +} + +void UITestCanvas::UIKitCanvasTestDrawPath011() +{ + if (container_ == nullptr) { + return; + } + CreateTitleLabel("moveTo + lineTo + moveTo + lineTo"); + UICanvas* canvas = CreateCanvas(); + + Paint paint; + canvas->BeginPath(); + canvas->MoveTo({ START1_X, START1_Y }); + canvas->LineTo({ LINE1_X, LINE1_Y }); + canvas->MoveTo({ START2_X, START2_Y }); + canvas->LineTo({ LINE2_X, LINE2_Y }); + canvas->DrawPath(paint); +} + +void UITestCanvas::UIKitCanvasTestDrawPath012() +{ + if (container_ == nullptr) { + return; + } + CreateTitleLabel("moveTo + lineTo + arc"); + UICanvas* canvas = CreateCanvas(); + + Paint paint; + canvas->BeginPath(); + canvas->MoveTo({ START1_X, START1_Y }); + canvas->LineTo({ LINE1_X, LINE1_Y }); + canvas->ArcTo({ CENTER_X, CENTER_Y }, RADIUS, START_ANGLE, END_ANGLE); + canvas->DrawPath(paint); +} + +void UITestCanvas::UIKitCanvasTestDrawPath013() +{ + if (container_ == nullptr) { + return; + } + CreateTitleLabel("moveTo + lineTo + arc + closePath"); + UICanvas* canvas = CreateCanvas(); + + Paint paint; + canvas->BeginPath(); + canvas->MoveTo({ START1_X, START1_Y }); + canvas->LineTo({ LINE1_X, LINE1_Y }); + canvas->ArcTo({ CENTER_X, CENTER_Y }, RADIUS, START_ANGLE, END_ANGLE); + canvas->ClosePath(); + canvas->DrawPath(paint); +} + +void UITestCanvas::UIKitCanvasTestDrawPath014() +{ + if (container_ == nullptr) { + return; + } + CreateTitleLabel("moveTo + lineTo + rect"); + UICanvas* canvas = CreateCanvas(); + + Paint paint; + canvas->BeginPath(); + canvas->MoveTo({ START1_X, START1_Y }); + canvas->LineTo({ LINE1_X, LINE1_Y }); + canvas->AddRect({ RECT_X, RECT_Y }, RECT_HEIGHT, RECT_WIDTH); + canvas->DrawPath(paint); +} + +void UITestCanvas::UIKitCanvasTestDrawPath015() +{ + if (container_ == nullptr) { + return; + } + CreateTitleLabel("moveTo + lineTo + rect + closePath"); + UICanvas* canvas = CreateCanvas(); + + Paint paint; + canvas->BeginPath(); + canvas->MoveTo({ START1_X, START1_Y }); + canvas->LineTo({ LINE1_X, LINE1_Y }); + canvas->AddRect({ RECT_X, RECT_Y }, RECT_HEIGHT, RECT_WIDTH); + canvas->ClosePath(); + canvas->DrawPath(paint); +} + +void UITestCanvas::UIKitCanvasTestDrawPath016() +{ + if (container_ == nullptr) { + return; + } + CreateTitleLabel("rect + lineTo"); + UICanvas* canvas = CreateCanvas(); + + Paint paint; + canvas->BeginPath(); + canvas->AddRect({ RECT_X, RECT_Y }, RECT_HEIGHT, RECT_WIDTH); + canvas->LineTo({ LINE1_X, LINE1_Y }); + canvas->DrawPath(paint); +} + +void UITestCanvas::UIKitCanvasTestDrawPath017() +{ + if (container_ == nullptr) { + return; + } + CreateTitleLabel("rect + moveTo + lineTo"); + UICanvas* canvas = CreateCanvas(); + + Paint paint; + canvas->BeginPath(); + canvas->AddRect({ RECT_X, RECT_Y }, RECT_HEIGHT, RECT_WIDTH); + canvas->MoveTo({ START1_X, START1_Y }); + canvas->LineTo({ LINE1_X, LINE1_Y }); + canvas->DrawPath(paint); +} + +void UITestCanvas::UIKitCanvasTestDrawPath018() +{ + if (container_ == nullptr) { + return; + } + CreateTitleLabel("rect + arc"); + UICanvas* canvas = CreateCanvas(); + + Paint paint; + canvas->BeginPath(); + canvas->AddRect({ RECT_X, RECT_Y }, RECT_HEIGHT, RECT_WIDTH); + canvas->ArcTo({ CENTER_X, CENTER_Y }, RADIUS, START_ANGLE, END_ANGLE); + canvas->DrawPath(paint); +} + +void UITestCanvas::UIKitCanvasTestDrawPath019() +{ + if (container_ == nullptr) { + return; + } + CreateTitleLabel("arc + rect"); + UICanvas* canvas = CreateCanvas(); + + Paint paint; + canvas->BeginPath(); + canvas->ArcTo({ CENTER_X, CENTER_Y }, RADIUS, START_ANGLE, END_ANGLE); + canvas->AddRect({ RECT_X, RECT_Y }, RECT_HEIGHT, RECT_WIDTH); + canvas->DrawPath(paint); +} + +void UITestCanvas::UIKitCanvasTestDrawPath020() +{ + if (container_ == nullptr) { + return; + } + CreateTitleLabel("moveTo + arc + closePath + lineTo"); + UICanvas* canvas = CreateCanvas(); + + Paint paint; + canvas->BeginPath(); + canvas->MoveTo({ START1_X, START1_Y }); + canvas->ArcTo({ CENTER_X, CENTER_Y }, RADIUS, START_ANGLE, END_ANGLE); + canvas->ClosePath(); + canvas->LineTo({ LINE1_X, LINE1_Y }); + canvas->DrawPath(paint); +} + +void UITestCanvas::UIKitCanvasTestDrawPath021() +{ + if (container_ == nullptr) { + return; + } + CreateTitleLabel("不调用beginPath,无显示"); + UICanvas* canvas = CreateCanvas(); + + Paint paint; + canvas->MoveTo({ START1_X, START1_Y }); + canvas->ArcTo({ CENTER_X, CENTER_Y }, RADIUS, START_ANGLE, END_ANGLE); + canvas->ClosePath(); + canvas->LineTo({ LINE1_X, LINE1_Y }); + canvas->DrawPath(paint); +} + +void UITestCanvas::UIKitCanvasTestDrawPath022() +{ + if (container_ == nullptr) { + return; + } + CreateTitleLabel("不调用drawPath,无显示"); + UICanvas* canvas = CreateCanvas(); + + Paint paint; + canvas->BeginPath(); + canvas->MoveTo({ START1_X, START1_Y }); + canvas->ArcTo({ CENTER_X, CENTER_Y }, RADIUS, START_ANGLE, END_ANGLE); + canvas->ClosePath(); + canvas->LineTo({ LINE1_X, LINE1_Y }); +} + +void UITestCanvas::UIKitCanvasTestDrawPath023() +{ + if (container_ == nullptr) { + return; + } + CreateTitleLabel("moveTo + lineTo + closePath"); + UICanvas* canvas = CreateCanvas(); + + Paint paint; + canvas->BeginPath(); + canvas->MoveTo({ START1_X, START1_Y }); + canvas->LineTo({ LINE1_X, LINE1_Y }); + canvas->ClosePath(); + canvas->DrawPath(paint); +} + +void UITestCanvas::UIKitCanvasTestDrawPath024() +{ + if (container_ == nullptr) { + return; + } + CreateTitleLabel("moveTo + closePath,无显示"); + UICanvas* canvas = CreateCanvas(); + + Paint paint; + canvas->BeginPath(); + canvas->MoveTo({ START1_X, START1_Y }); + canvas->ClosePath(); + canvas->DrawPath(paint); +} + +void UITestCanvas::UIKitCanvasTestDrawPath025() +{ + if (container_ == nullptr) { + return; + } + CreateTitleLabel("多次drawPath"); + UICanvas* canvas = CreateCanvas(); + + Paint paint; + canvas->BeginPath(); + canvas->MoveTo({ START1_X, START1_Y }); + canvas->LineTo({ LINE1_X, LINE1_Y }); + canvas->DrawPath(paint); + paint.SetStrokeColor(Color::Blue()); + paint.SetStrokeWidth(1); + canvas->LineTo({ LINE2_X, LINE2_Y }); + canvas->DrawPath(paint); +} + +void UITestCanvas::UIKitCanvasTestDrawPath026() +{ + if (container_ == nullptr) { + return; + } + CreateTitleLabel("arc起止角度互换"); + UICanvas* canvas = CreateCanvas(); + + Paint paint; + canvas->BeginPath(); + canvas->MoveTo({ START1_X, START1_Y }); + canvas->ArcTo({ CENTER_X, CENTER_Y }, RADIUS, START_ANGLE, END_ANGLE); + + canvas->MoveTo({ START2_X, START2_Y }); + canvas->ArcTo({ CENTER_X + CENTER_X, CENTER_Y }, RADIUS, END_ANGLE, START_ANGLE); + + canvas->DrawPath(paint); +} + +void UITestCanvas::UIKitCanvasTestDrawPath027() +{ + if (container_ == nullptr) { + return; + } + CreateTitleLabel("arc扫描范围超过360度 "); + UICanvas* canvas = CreateCanvas(); + + Paint paint; + canvas->BeginPath(); + canvas->MoveTo({ START1_X, START1_Y }); + canvas->ArcTo({ CENTER_X, CENTER_Y }, RADIUS, START_ANGLE, START_ANGLE + CIRCLE_IN_DEGREE + QUARTER_IN_DEGREE); + canvas->ArcTo({ CENTER_X + CENTER_X, CENTER_Y }, RADIUS, END_ANGLE, START_ANGLE + CIRCLE_IN_DEGREE); + + canvas->DrawPath(paint); +} + +void UITestCanvas::UIKitCanvasTestDrawPath028() +{ + if (container_ == nullptr) { + return; + } + CreateTitleLabel("创建两条路径,只绘制后一条 "); + UICanvas* canvas = CreateCanvas(); + + Paint paint; + canvas->BeginPath(); + canvas->MoveTo({ START1_X, START1_Y }); + canvas->ArcTo({ CENTER_X, CENTER_Y }, RADIUS, START_ANGLE, START_ANGLE + CIRCLE_IN_DEGREE); + + canvas->BeginPath(); + canvas->MoveTo({ START2_X, START2_Y }); + canvas->ArcTo({ CENTER_X + CENTER_X, CENTER_Y }, RADIUS, END_ANGLE, START_ANGLE + CIRCLE_IN_DEGREE); + + canvas->DrawPath(paint); +} + +void UITestCanvas::UIKitCanvasTestDrawPath029() +{ + if (container_ == nullptr) { + return; + } + CreateTitleLabel("绘制两条不同样式的路径 "); + UICanvas* canvas = CreateCanvas(); + + Paint paint; + canvas->BeginPath(); + canvas->MoveTo({ START1_X, START1_Y }); + canvas->ArcTo({ CENTER_X, CENTER_Y }, RADIUS, START_ANGLE, START_ANGLE + CIRCLE_IN_DEGREE); + canvas->DrawPath(paint); + + canvas->BeginPath(); + canvas->MoveTo({ START2_X, START2_Y }); + canvas->ArcTo({ CENTER_X + CENTER_X, CENTER_Y }, RADIUS, END_ANGLE, START_ANGLE + CIRCLE_IN_DEGREE); + paint.SetStrokeColor(Color::Blue()); + canvas->DrawPath(paint); +} + +void UITestCanvas::UIKitCanvasTestDrawPath030() +{ + if (container_ == nullptr) { + return; + } + CreateTitleLabel("同一条路径绘制100遍 "); + UICanvas* canvas = CreateCanvas(); + + Paint paint; + canvas->BeginPath(); + canvas->MoveTo({ START1_X, START1_Y }); + canvas->LineTo({ LINE1_X, LINE1_Y }); + canvas->ArcTo({ CENTER_X, CENTER_Y }, RADIUS, START_ANGLE, START_ANGLE + CIRCLE_IN_DEGREE); + canvas->AddRect({ RECT_X, RECT_Y }, RECT_HEIGHT, RECT_WIDTH); + for (uint8_t i = 0; i < 100; i++) { // 100: number of times for drawing loops + canvas->DrawPath(paint); + } +} + +void UITestCanvas::UIKitCanvasTestDrawPath031() +{ + if (container_ == nullptr) { + return; + } + CreateTitleLabel("绘制直线超出canvas范围"); + UICanvas* canvas = CreateCanvas(); + + Paint paint; + canvas->BeginPath(); + canvas->MoveTo({ START1_X, START1_Y }); + canvas->LineTo({ LINE1_X + HORIZONTAL_RESOLUTION, LINE1_Y }); + canvas->LineTo({ LINE2_X, LINE2_Y }); + canvas->DrawPath(paint); +} + +void UITestCanvas::UIKitCanvasTestDrawPath032() +{ + if (container_ == nullptr) { + return; + } + CreateTitleLabel("绘制直线传入临界值 "); + UICanvas* canvas = CreateCanvas(); + + Paint paint; + canvas->BeginPath(); + canvas->MoveTo({ INT16_MAX, INT16_MAX }); + canvas->LineTo({ 0, 0 }); + + canvas->MoveTo({ 0, 0 }); + canvas->LineTo({ INT16_MAX, INT16_MAX }); + + canvas->MoveTo({ INT16_MIN, INT16_MIN }); + canvas->LineTo({ 0, 0 }); + + canvas->MoveTo({ 0, 0 }); + canvas->LineTo({ INT16_MIN, INT16_MIN }); + canvas->DrawPath(paint); +} + + +void UITestCanvas::UIKitCanvasTestDrawPath033() +{ + if (container_ == nullptr) { + return; + } + + CreateTitleLabel("绘制arc传入临界值 "); + UICanvas* canvas = CreateCanvas(); + + Paint paint; + canvas->BeginPath(); + canvas->ArcTo({ INT16_MAX, INT16_MAX }, RADIUS, START_ANGLE, END_ANGLE); + canvas->DrawPath(paint); + + canvas->BeginPath(); + canvas->ArcTo({ INT16_MIN, INT16_MIN }, RADIUS, START_ANGLE, END_ANGLE); + paint.SetStrokeColor(Color::Red()); + canvas->DrawPath(paint); + + canvas->BeginPath(); + canvas->ArcTo({ CENTER_X, CENTER_Y }, UINT16_MAX, START_ANGLE, END_ANGLE); + paint.SetStrokeColor(Color::Yellow()); + canvas->DrawPath(paint); + + canvas->BeginPath(); + canvas->ArcTo({ CENTER_X + CENTER_X, CENTER_Y }, RADIUS, INT16_MIN, INT16_MAX); + paint.SetStrokeColor(Color::Blue()); + canvas->DrawPath(paint); +} + +void UITestCanvas::UIKitCanvasTestDrawPath034() +{ + if (container_ == nullptr) { + return; + } + + CreateTitleLabel("绘制rect传入临界值 "); + UICanvas* canvas = CreateCanvas(); + + Paint paint; + canvas->BeginPath(); + canvas->AddRect({ INT16_MAX, INT16_MAX }, RECT_HEIGHT, RECT_WIDTH); + canvas->DrawPath(paint); + + canvas->BeginPath(); + canvas->AddRect({ RECT_X, RECT_Y }, INT16_MAX, INT16_MAX); + paint.SetStrokeColor(Color::Red()); + canvas->DrawPath(paint); +} +} // namespace OHOS \ No newline at end of file diff --git a/test/uitest/test_canvas/ui_test_canvas.h b/test/uitest/test_canvas/ui_test_canvas.h new file mode 100755 index 0000000..61e91a6 --- /dev/null +++ b/test/uitest/test_canvas/ui_test_canvas.h @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef UI_TEST_CANVAS_H +#define UI_TEST_CANVAS_H + +#include "components/ui_canvas.h" +#include "components/ui_label_button.h" +#include "components/ui_scroll_view.h" +#include "layout/grid_layout.h" +#include "ui_test.h" + +namespace OHOS { +class UITestCanvas : public UITest { +public: + UITestCanvas() {} + ~UITestCanvas() {} + void SetUp() override; + void TearDown() override; + UIView* GetTestView() override; + + void UIKitCanvasTestDrawLine001(); + void UIKitCanvasTestDrawLine002(); + void UIKitCanvasTestDrawCurve001(); + void UIKitCanvasTestDrawCurve002(); + void UIKitCanvasTestDrawRect001(); + void UIKitCanvasTestDrawRect002(); + void UIKitCanvasTestDrawRect003(); + void UIKitCanvasTestDrawCircle001(); + void UIKitCanvasTestDrawCircle002(); + void UIKitCanvasTestDrawCircle003(); + void UIKitCanvasTestDrawArc001(); + void UIKitCanvasTestDrawImage001(); + void UIKitCanvasTestDrawLabel001(); + void UIKitCanvasTestDrawSector001(); + void UIKitCanvasTestClear001(); + void UIKitCanvasTestDrawPath001(); + void UIKitCanvasTestDrawPath002(); + void UIKitCanvasTestDrawPath003(); + void UIKitCanvasTestDrawPath004(); + void UIKitCanvasTestDrawPath005(); + void UIKitCanvasTestDrawPath006(); + void UIKitCanvasTestDrawPath007(); + void UIKitCanvasTestDrawPath008(); + void UIKitCanvasTestDrawPath009(); + void UIKitCanvasTestDrawPath010(); + void UIKitCanvasTestDrawPath011(); + void UIKitCanvasTestDrawPath012(); + void UIKitCanvasTestDrawPath013(); + void UIKitCanvasTestDrawPath014(); + void UIKitCanvasTestDrawPath015(); + void UIKitCanvasTestDrawPath016(); + void UIKitCanvasTestDrawPath017(); + void UIKitCanvasTestDrawPath018(); + void UIKitCanvasTestDrawPath019(); + void UIKitCanvasTestDrawPath020(); + void UIKitCanvasTestDrawPath021(); + void UIKitCanvasTestDrawPath022(); + void UIKitCanvasTestDrawPath023(); + void UIKitCanvasTestDrawPath024(); + void UIKitCanvasTestDrawPath025(); + void UIKitCanvasTestDrawPath026(); + void UIKitCanvasTestDrawPath027(); + void UIKitCanvasTestDrawPath028(); + void UIKitCanvasTestDrawPath029(); + void UIKitCanvasTestDrawPath030(); + void UIKitCanvasTestDrawPath031(); + void UIKitCanvasTestDrawPath032(); + void UIKitCanvasTestDrawPath033(); + void UIKitCanvasTestDrawPath034(); + +private: + const static int16_t GAP = 10; + const static int16_t TITLE_HEIGHT = 29; + const static uint16_t CANVAS_WIDTH = 454; + const static uint16_t CANVAS_HEIGHT = 200; + + static constexpr int16_t START1_X = 10; + static constexpr int16_t START1_Y = 10; + static constexpr int16_t START2_X = 80; + static constexpr int16_t START2_Y = 10; + static constexpr int16_t LINE1_X = 40; + static constexpr int16_t LINE1_Y = 100; + static constexpr int16_t LINE2_X = 100; + static constexpr int16_t LINE2_Y = 120; + static constexpr int16_t CENTER_X = 150; + static constexpr int16_t CENTER_Y = 150; + static constexpr int16_t RADIUS = 50; + static constexpr int16_t START_ANGLE = 30; + static constexpr int16_t END_ANGLE = 250; + static constexpr int16_t RECT_X = 250; + static constexpr int16_t RECT_Y = 50; + static constexpr int16_t RECT_WIDTH = 100; + static constexpr int16_t RECT_HEIGHT = 50; + void CreateTitleLabel(const char* title); + UICanvas* CreateCanvas(); + + UIScrollView* container_ = nullptr; +}; +} // namespace OHOS +#endif // UI_TEST_CANVAS_H diff --git a/test/uitest/test_chart/ui_test_chart_pillar.cpp b/test/uitest/test_chart/ui_test_chart_pillar.cpp new file mode 100755 index 0000000..6551dcd --- /dev/null +++ b/test/uitest/test_chart/ui_test_chart_pillar.cpp @@ -0,0 +1,225 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "ui_test_chart_pillar.h" +#include "common/screen.h" + +namespace OHOS { +namespace { + static int16_t g_blank = 20; +} + +void UITestChartPillar::SetUp() +{ + if (container_ == nullptr) { + container_ = new UIScrollView(); + container_->Resize(Screen::GetInstance().GetWidth(), Screen::GetInstance().GetHeight() - BACK_BUTTON_HEIGHT); + container_->SetThrowDrag(true); + } + + dataSerial_[0] = new UIChartDataSerial(); + dataSerial_[0]->SetMaxDataCount(5); // 5: number of data points + Point pointArray[5] = {{0, 2478}, {1, 2600}, {2, 3000}, {3, 3200}, {4, 3500}}; + dataSerial_[0]->AddPoints(pointArray, 5); // 5: number of data points + dataSerial_[0]->SetFillColor(Color::Red()); + + dataSerial_[1] = new UIChartDataSerial(); + dataSerial_[1]->SetMaxDataCount(5); // 5: number of data points + Point pointArray1[5] = {{0, 2000}, {1, 0}, {2, 800}, {3, 700}, {4, 433}}; + dataSerial_[1]->AddPoints(pointArray1, 5); // 5: number of data points + dataSerial_[1]->SetFillColor(Color::Green()); + + dataSerial_[2] = new UIChartDataSerial(); // 2 array index + dataSerial_[2]->SetMaxDataCount(5); // 2 array index, 5: number of data points + Point pointArray2[5] = {{0, 100}, {1, 200}, {2, 300}, {3, 400}, {4, 500}}; + dataSerial_[2]->AddPoints(pointArray2, 5); // 2 array index, 5: number of data points + dataSerial_[2]->SetFillColor(Color::Blue()); // 2 array index + curDataIndex_ = 0; +} + +void UITestChartPillar::InnerDeleteChildren(UIView* view) const +{ + if (view == nullptr) { + return; + } + while (view != nullptr) { + UIView* tempView = view; + view = view->GetNextSibling(); + if (tempView->IsViewGroup()) { + InnerDeleteChildren(static_cast(tempView)->GetChildrenHead()); + } + if (tempView->GetViewType() == UI_AXIS) { + return; + } + if (tempView->GetParent()) { + static_cast(tempView->GetParent())->Remove(tempView); + } + delete tempView; + } +} + +void UITestChartPillar::TearDown() +{ + chart_->ClearDataSerial(); + for (uint8_t i = 0; i < DATA_NUM; i++) { + delete dataSerial_[i]; + dataSerial_[i] = nullptr; + } + InnerDeleteChildren(container_); + container_ = nullptr; + lastX_ = 0; + lastY_ = 0; + positionX_ = 0; + positionY_ = 0; +} + +UIView* UITestChartPillar::GetTestView() +{ + UIKit_ChartPillar_Test_AddDataSerial_001(); + UIKit_ChartPillar_Test_EnableReverse_002(); + UIKit_ChartPillar_Test_SetAxisLineColor_003(); + UIKit_ChartPillar_Test_SetAxisLineVisible_004(); + return container_; +} + +void UITestChartPillar::UIKit_ChartPillar_Test_AddDataSerial_001() +{ + UILabel* label = GetTitleLabel("UIChartPillar效果 "); + label->SetPosition(TEXT_DISTANCE_TO_LEFT_SIDE, TEXT_DISTANCE_TO_TOP_SIDE); + container_->Add(label); + + chart_ = new UIChartPillar(); + chart_->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE, VIEW_DISTANCE_TO_TOP_SIDE); + chart_->SetWidth(454); // 454: width + chart_->SetHeight(250); // 250: height + + UIXAxis& xAxis = chart_->GetXAxis(); + UIYAxis& yAxis = chart_->GetYAxis(); + xAxis.SetMarkNum(5); // 5: number of scales + yAxis.SetDataRange(0, 5000); // 0: minimum value, 5000: maximum value + + chart_->AddDataSerial(dataSerial_[0]); + curDataIndex_++; + container_->Add(chart_); + SetLastPos(chart_); + + addDataSerialBtn_ = new UILabelButton(); + deleteDataSerialBtn_ = new UILabelButton(); + clearDataSerialBtn_ = new UILabelButton(); + + positionY_ = lastY_ + 10; // 10: increase y-coordinate + positionX_ = 48; // 48: x-coordinate + SetUpButton(addDataSerialBtn_, "添加数据 "); + + positionX_ = addDataSerialBtn_->GetX() + addDataSerialBtn_->GetWidth() + g_blank; + positionY_ = addDataSerialBtn_->GetY(); + SetUpButton(deleteDataSerialBtn_, "删除数据 "); + + positionX_ = deleteDataSerialBtn_->GetX() + deleteDataSerialBtn_->GetWidth() + g_blank; + positionY_ = deleteDataSerialBtn_->GetY(); + SetUpButton(clearDataSerialBtn_, "清空数据 "); +} + +void UITestChartPillar::UIKit_ChartPillar_Test_EnableReverse_002() +{ + reverseBtn_ = new UILabelButton(); + positionX_ = 48; // 48: x-coordinate + SetUpButton(reverseBtn_, "翻转 "); +} + +void UITestChartPillar::UIKit_ChartPillar_Test_SetAxisLineColor_003() +{ + setAxisColorBtn_ = new UILabelButton(); + positionX_ = reverseBtn_->GetX() + reverseBtn_->GetWidth() + g_blank; + positionY_ = reverseBtn_->GetY(); + SetUpButton(setAxisColorBtn_, "坐标轴颜色 "); +} + +void UITestChartPillar::UIKit_ChartPillar_Test_SetAxisLineVisible_004() +{ + setAxisVisibleBtn_ = new UILabelButton(); + positionX_ = setAxisColorBtn_->GetX() + setAxisColorBtn_->GetWidth() + g_blank; + positionY_ = setAxisColorBtn_->GetY(); + SetUpButton(setAxisVisibleBtn_, "坐标轴不可见"); +} + +bool UITestChartPillar::OnClick(UIView& view, const ClickEvent& event) +{ + if (&view == addDataSerialBtn_) { + if (curDataIndex_ >= DATA_NUM) { + return true; + } + chart_->AddDataSerial(dataSerial_[curDataIndex_]); + curDataIndex_++; + chart_->Invalidate(); + } else if (&view == deleteDataSerialBtn_) { + if (curDataIndex_ <= 0) { + return true; + } + chart_->DeleteDataSerial(dataSerial_[curDataIndex_ - 1]); + curDataIndex_--; + chart_->Invalidate(); + } else if (&view == clearDataSerialBtn_) { + chart_->ClearDataSerial(); + curDataIndex_ = 0; + chart_->Invalidate(); + } else if (&view == reverseBtn_) { + chart_->EnableReverse(true); + chart_->Invalidate(); + } else if (&view == setAxisColorBtn_) { + UIXAxis& xAxis = chart_->GetXAxis(); + UIYAxis& yAxis = chart_->GetYAxis(); + xAxis.SetLineColor(Color::Red()); + yAxis.SetLineColor(Color::Red()); + chart_->Invalidate(); + } else if (&view == setAxisVisibleBtn_) { + UIXAxis& xAxis = chart_->GetXAxis(); + UIYAxis& yAxis = chart_->GetYAxis(); + xAxis.SetVisible(false); + yAxis.SetVisible(false); + chart_->Invalidate(); + } + return true; +} + +void UITestChartPillar::SetUpButton(UILabelButton* btn, const char* title) +{ + if (btn == nullptr) { + return; + } + container_->Add(btn); + btn->SetPosition(positionX_, positionY_, BUTTON_WIDHT2, BUTTON_HEIGHT2); + positionY_ += btn->GetHeight() + 10; // 10: increase height + btn->SetText(title); + btn->SetFont(DEFAULT_VECTOR_FONT_FILENAME, BUTTON_LABEL_SIZE); + btn->SetOnClickListener(this); + btn->SetStyleForState(STYLE_BORDER_RADIUS, BUTTON_STYLE_BORDER_RADIUS_VALUE, UIButton::RELEASED); + btn->SetStyleForState(STYLE_BORDER_RADIUS, BUTTON_STYLE_BORDER_RADIUS_VALUE, UIButton::PRESSED); + btn->SetStyleForState(STYLE_BORDER_RADIUS, BUTTON_STYLE_BORDER_RADIUS_VALUE, UIButton::INACTIVE); + btn->SetStyleForState(STYLE_BACKGROUND_COLOR, BUTTON_STYLE_BACKGROUND_COLOR_VALUE, UIButton::RELEASED); + btn->SetStyleForState(STYLE_BACKGROUND_COLOR, BUTTON_STYLE_BACKGROUND_COLOR_VALUE, UIButton::PRESSED); + btn->SetStyleForState(STYLE_BACKGROUND_COLOR, BUTTON_STYLE_BACKGROUND_COLOR_VALUE, UIButton::INACTIVE); + container_->Invalidate(); +} + +void UITestChartPillar::SetLastPos(UIView* view) +{ + if (view == nullptr) { + return; + } + lastX_ = view->GetX(); + lastY_ = view->GetY() + view->GetHeight(); +} +} // namespace OHOS \ No newline at end of file diff --git a/test/uitest/test_chart/ui_test_chart_pillar.h b/test/uitest/test_chart/ui_test_chart_pillar.h new file mode 100755 index 0000000..a1f993f --- /dev/null +++ b/test/uitest/test_chart/ui_test_chart_pillar.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef UI_TEST_CHART_PILLAR_H +#define UI_TEST_CHART_PILLAR_H + +#include "components/ui_chart.h" +#include "components/ui_label.h" +#include "components/ui_label_button.h" +#include "components/ui_scroll_view.h" +#include "ui_test.h" + +namespace OHOS { +class UITestChartPillar : public UITest, public UIView::OnClickListener { +public: + UITestChartPillar() : dataSerial_() {} + ~UITestChartPillar() {} + void SetUp() override; + void TearDown() override; + UIView* GetTestView() override; + + void SetUpButton(UILabelButton* btn, const char* title); + + bool OnClick(UIView& view, const ClickEvent& event) override; + + void UIKit_ChartPillar_Test_AddDataSerial_001(); + void UIKit_ChartPillar_Test_EnableReverse_002(); + void UIKit_ChartPillar_Test_SetAxisLineColor_003(); + void UIKit_ChartPillar_Test_SetAxisLineVisible_004(); + +private: + void SetLastPos(UIView* view); + void InnerDeleteChildren(UIView* view) const; + static constexpr uint8_t DATA_NUM = 3; + UIChartDataSerial *dataSerial_[DATA_NUM]; + uint8_t curDataIndex_ = 0; + + UIScrollView* container_ = nullptr; + UIChartPillar* chart_ = nullptr; + UILabelButton* addDataSerialBtn_ = nullptr; + UILabelButton* deleteDataSerialBtn_ = nullptr; + UILabelButton* clearDataSerialBtn_ = nullptr; + UILabelButton* reverseBtn_ = nullptr; + UILabelButton* setAxisColorBtn_ = nullptr; + UILabelButton* setAxisVisibleBtn_ = nullptr; + + int16_t lastX_ = 0; + int16_t lastY_ = 0; +}; +} // namespace OHOS +#endif // UI_TEST_CHART_PILLAR_H diff --git a/test/uitest/test_chart/ui_test_chart_polyline.cpp b/test/uitest/test_chart/ui_test_chart_polyline.cpp new file mode 100755 index 0000000..59ad7ad --- /dev/null +++ b/test/uitest/test_chart/ui_test_chart_polyline.cpp @@ -0,0 +1,416 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "ui_test_chart_polyline.h" +#include "common/screen.h" + +namespace OHOS { +namespace { +static int16_t g_blank = 20; +static int g_curSerialCount = 0; +static int g_curArrayCount = 0; +static bool g_secondScreenFlag = false; +static bool g_addPointsFlag = false; +static bool g_hidePointsFlag = false; +} // namespace + +void UITestChartPolyline::SetUp() +{ + if (container_ == nullptr) { + container_ = new UIScrollView(); + container_->Resize(Screen::GetInstance().GetWidth(), Screen::GetInstance().GetHeight() - BACK_BUTTON_HEIGHT); + container_->SetHorizontalScrollState(false); + container_->SetThrowDrag(true); + } + + dataSerial_[0] = new UIChartDataSerial(); + dataSerial_[0]->SetMaxDataCount(5); // 5: number of data points + Point pointArray[5] = {{0, 2478}, {1, 2600}, {2, 3000}, {3, 3200}, {4, 3500}}; + dataSerial_[0]->AddPoints(pointArray, 5); // 5: number of data points + dataSerial_[0]->SetLineColor(Color::Red()); + dataSerial_[0]->SetFillColor(Color::Red()); + dataSerial_[0]->EnableGradient(true); + + dataSerial_[1] = new UIChartDataSerial(); + dataSerial_[1]->SetMaxDataCount(5); // 5: number of data points + Point pointArray1[5] = {{0, 2000}, {1, 0}, {2, 800}, {3, 700}, {4, 433}}; + dataSerial_[1]->AddPoints(pointArray1, 5); // 5: number of data points + dataSerial_[1]->SetLineColor(Color::Green()); + dataSerial_[1]->SetFillColor(Color::Green()); + dataSerial_[1]->EnableGradient(true); + + dataSerial_[2] = new UIChartDataSerial(); // 2: array index + dataSerial_[2]->SetMaxDataCount(5); // 2: array index, 5: number of data points + Point pointArray2[5] = {{0, 100}, {1, 200}, {2, 300}, {3, 400}, {4, 500}}; + dataSerial_[2]->AddPoints(pointArray2, 5); // 2: array index, 5: number of data points + dataSerial_[2]->SetLineColor(Color::Blue()); // 2: array index + curDataIndex_ = 0; +} + +void UITestChartPolyline::InnerDeleteChildren(UIView* view) const +{ + if (view == nullptr) { + return; + } + while (view != nullptr) { + UIView* tempView = view; + view = view->GetNextSibling(); + if (tempView->IsViewGroup()) { + InnerDeleteChildren(static_cast(tempView)->GetChildrenHead()); + } + if (tempView->GetViewType() == UI_AXIS) { + return; + } + if (tempView->GetParent()) { + static_cast(tempView->GetParent())->Remove(tempView); + } + delete tempView; + } +} + +void UITestChartPolyline::TearDown() +{ + ECGAnimator_->Stop(); + AnimatorManager::GetInstance()->Remove(ECGAnimator_); + delete ECGAnimator_; + ECGAnimator_ = nullptr; + chart_->ClearDataSerial(); + for (uint8_t i = 0; i < DATA_NUM; i++) { + delete dataSerial_[i]; + dataSerial_[i] = nullptr; + } + InnerDeleteChildren(container_); + container_ = nullptr; + lastX_ = 0; + lastY_ = 0; + positionX_ = 0; + positionY_ = 0; + g_curSerialCount = 0; + g_curArrayCount = 0; + g_secondScreenFlag = false; + g_addPointsFlag = false; + g_hidePointsFlag = false; +} + +UIView* UITestChartPolyline::GetTestView() +{ + UIKit_ChartPolyline_Test_AddDataSerial_001(); + UIKit_ChartPolyline_Test_EnableReverse_002(); + UIKit_ChartPolyline_Test_SetGradientBottom_003(); + UIKit_ChartPolyline_Test_AddPoints_004(); + + return container_; +} + +void UITestChartPolyline::UIKit_ChartPolyline_Test_AddDataSerial_001() +{ + UILabel* label = new UILabel(); + container_->Add(label); + lastY_ = TEXT_DISTANCE_TO_TOP_SIDE; + // 29: label height + label->SetPosition(TEXT_DISTANCE_TO_LEFT_SIDE, lastY_, Screen::GetInstance().GetWidth(), 29); + label->SetText("chart添加、删除数据串 "); + label->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); + + chart_ = new UIChartPolyline(); + chart_->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE, VIEW_DISTANCE_TO_TOP_SIDE); + chart_->SetWidth(454); // 454: width + chart_->SetHeight(250); // 250: height + + UIXAxis& xAxis = chart_->GetXAxis(); + UIYAxis& yAxis = chart_->GetYAxis(); + xAxis.SetMarkNum(5); // 5: number of scales + xAxis.SetDataRange(0, 5); // 0: minimum value, 5: maximum value + yAxis.SetDataRange(0, 5000); // 0: minimum value, 5000: maximum value + + chart_->SetGradientOpacity(25, 127); // 25: min opacity, 127: max opacity + chart_->AddDataSerial(dataSerial_[0]); + curDataIndex_++; + container_->Add(chart_); + SetLastPos(chart_); + + addDataSerialBtn_ = new UILabelButton(); + deleteDataSerialBtn_ = new UILabelButton(); + clearDataSerialBtn_ = new UILabelButton(); + topPointBtn_ = new UILabelButton(); + bottomPointBtn_ = new UILabelButton(); + headPointBtn_ = new UILabelButton(); + + positionX_ = VIEW_DISTANCE_TO_LEFT_SIDE; + positionY_ = lastY_ + 10; // 10: increase y-coordinate + SetUpButton(addDataSerialBtn_, "添加数据 "); + positionX_ = addDataSerialBtn_->GetX() + addDataSerialBtn_->GetWidth() + g_blank; + positionY_ = addDataSerialBtn_->GetY(); + SetUpButton(deleteDataSerialBtn_, "删除数据 "); + positionX_ = deleteDataSerialBtn_->GetX() + deleteDataSerialBtn_->GetWidth() + g_blank; + positionY_ = deleteDataSerialBtn_->GetY(); + SetUpButton(clearDataSerialBtn_, "清空数据 "); + + positionX_ = VIEW_DISTANCE_TO_LEFT_SIDE; + SetUpButton(topPointBtn_, "最高点 "); + positionX_ = topPointBtn_->GetX() + topPointBtn_->GetWidth() + g_blank; + positionY_ = topPointBtn_->GetY(); + SetUpButton(bottomPointBtn_, "最低点 "); + positionX_ = bottomPointBtn_->GetX() + bottomPointBtn_->GetWidth() + g_blank; + positionY_ = bottomPointBtn_->GetY(); + SetUpButton(headPointBtn_, "最新点 "); +} + +void UITestChartPolyline::UIKit_ChartPolyline_Test_EnableReverse_002() +{ + reverseBtn_ = new UILabelButton(); + positionX_ = VIEW_DISTANCE_TO_LEFT_SIDE; + SetUpButton(reverseBtn_, "翻转 "); + SetLastPos(reverseBtn_); +} + +void UITestChartPolyline::UIKit_ChartPolyline_Test_SetGradientBottom_003() +{ + gradientBottomBtn_ = new UILabelButton(); + positionX_ = reverseBtn_->GetX() + reverseBtn_->GetWidth() + g_blank; + positionY_ = reverseBtn_->GetY(); + SetUpButton(gradientBottomBtn_, "填充底部位置 "); + SetLastPos(gradientBottomBtn_); +} +namespace { +const int16_t DATA_COUNT = 480; +} +/* ECG test data */ +static int16_t g_ECGData[DATA_COUNT] = { + 68, 70, 73, 83, 95, 107, 118, 127, 118, 103, 90, 77, 66, 61, 57, 58, 60, 61, 62, 62, 63, 64, 64, 65, 67, 69, + 70, 71, 73, 75, 76, 78, 78, 79, 80, 80, 80, 80, 80, 80, 79, 78, 77, 76, 75, 73, 72, 71, 70, 70, 70, 70, + 70, 70, 70, 70, 71, 71, 71, 71, 71, 71, 72, 72, 72, 72, 73, 73, 73, 73, 74, 74, 74, 74, 75, 75, 75, 75, + 75, 75, 75, 75, 74, 74, 74, 74, 74, 74, 74, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 72, 71, + 71, 71, 70, 70, 70, 70, 71, 73, 75, 78, 80, 81, 82, 82, 82, 80, 78, 76, 73, 71, 69, 69, 68, 68, 68, 68, + 68, 70, 76, 88, 100, 111, 122, 126, 112, 98, 85, 73, 61, 58, 57, 59, 60, 61, 62, 62, 63, 64, 65, 66, 68, 69, + 70, 72, 74, 76, 77, 78, 79, 79, 80, 80, 80, 80, 79, 79, 79, 78, 77, 76, 74, 73, 72, 71, 70, 70, 70, 70, + 70, 70, 70, 71, 71, 71, 71, 71, 71, 72, 72, 72, 72, 73, 73, 73, 73, 74, 74, 74, 74, 74, 75, 75, 75, 75, + 75, 75, 75, 75, 74, 74, 74, 74, 74, 74, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 72, 72, 71, + 71, 70, 70, 69, 70, 70, 72, 74, 76, 78, 80, 82, 82, 82, 81, 79, 77, 75, 72, 70, 69, 68, 68, 68, 68, 68, + 69, 72, 80, 93, 104, 115, 126, 121, 106, 93, 80, 68, 59, 57, 58, 60, 61, 62, 62, 63, 63, 64, 65, 67, 68, 70, + 71, 73, 75, 76, 77, 78, 79, 80, 80, 80, 80, 80, 79, 79, 78, 78, 76, 75, 74, 72, 71, 70, 70, 70, 70, 70, + 70, 70, 70, 71, 71, 71, 71, 71, 71, 72, 72, 72, 73, 73, 73, 73, 74, 74, 74, 74, 74, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 74, 74, 74, 74, 74, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 72, 72, 71, + 71, 70, 70, 69, 70, 71, 72, 75, 77, 79, 81, 82, 82, 82, 80, 79, 76, 74, 71, 70, 69, 68, 68, 68, 68, 69, + 70, 75, 85, 97, 109, 120, 127, 115, 101, 88, 75, 64, 57, 56, 58, 60, 61, 62, 62, 63, 64, 65, 66, 67, 69, 71, + 72, 74, 75, 77, 78, 79, 79, 80, 80, 80, 80, 80, 79, 79, 78, 77, 76, 74, 73, 72, 71, 70, 70, 70, 70, 70, + 70, 70, 71, 71, 71, 71, 71, 71, 72, 72, 72, 72, 80, 93, 104, 115, 126, 121, 106, 93, 80, 68, 59, 57, 58, 60, + 61, 62, 62, 63, 63, 64, 65, 67, 68, 70, 71, 73}; + +class ImageAnimatorCallbackDemo : public OHOS::AnimatorCallback { +public: + explicit ImageAnimatorCallbackDemo(UIChartDataSerial* serial) : times_(0), serial_(serial) {} + + ~ImageAnimatorCallbackDemo() {} + + virtual void Callback(UIView* view) + { + if (view == nullptr) { + return; + } + if (!g_addPointsFlag) { + return; /* Control the addition of points by button, and automate if commented out */ + } + if (times_++ != 6) { /* Add 10 points for every 6 ticks */ + return; + } + times_ = 0; + if (g_curSerialCount == 0) { + view->Invalidate(); + } + Point pointArray1[10]; + for (uint16_t i = 0; i < 10; i++) { // 10: array max index + pointArray1[i].x = g_curSerialCount; + pointArray1[i].y = g_ECGData[g_curArrayCount]; + g_curSerialCount++; + g_curArrayCount++; + if (g_curArrayCount == DATA_COUNT) { + g_curArrayCount = 0; + } + if (!g_secondScreenFlag) { + serial_->AddPoints(&pointArray1[i], 1); + } else { + serial_->ModifyPoint(g_curSerialCount, pointArray1[i]); + if (g_hidePointsFlag) { + serial_->HidePoint(g_curSerialCount, 30); // 30: the number of points + } + } + } + if (g_curSerialCount > 454) { // 454: max serial count + g_curSerialCount = 0; + g_secondScreenFlag = true; + } + + UIChart* chart = static_cast(view); + chart->RefreshChart(); + g_addPointsFlag = false; + } + +protected: + int16_t times_; + UIChartDataSerial* serial_; +}; + +void UITestChartPolyline::UIKit_ChartPolyline_Test_AddPoints_004() +{ + UIViewGroup* uiViewGroup = new UIViewGroup(); + // 2: x-coordinate, half of screen width; 2: half of screen width; 470: screen height + uiViewGroup->SetPosition(Screen::GetInstance().GetWidth() / 2, 0, Screen::GetInstance().GetWidth() / 2, 470); + container_->Add(uiViewGroup); + + UILabel* label = new UILabel(); + uiViewGroup->Add(label); + label->SetPosition(TEXT_DISTANCE_TO_LEFT_SIDE, TEXT_DISTANCE_TO_TOP_SIDE, + Screen::GetInstance().GetWidth() / 2 - TEXT_DISTANCE_TO_LEFT_SIDE, // 2: half of screen width; + TITLE_LABEL_DEFAULT_HEIGHT); + label->SetText("chart追加点、修改点、平滑化"); + label->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); + + ECGChart_ = new UIChartPolyline(); + // 454: new width, 250: new height + ECGChart_->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE, VIEW_DISTANCE_TO_TOP_SIDE, 454, 250); + uiViewGroup->Add(ECGChart_); + SetLastPos(ECGChart_); + ECGChart_->SetStyle(STYLE_LINE_WIDTH, 5); // 5: line width + + UIXAxis& xAxis = ECGChart_->GetXAxis(); + UIYAxis& yAxis = ECGChart_->GetYAxis(); + xAxis.SetDataRange(0, 454); // 454: maximum value + xAxis.SetMarkNum(10); // 10: number of scales + yAxis.SetDataRange(0, 200); // 200: maximum value + + ECGDataSerial_ = new UIChartDataSerial(); + ECGDataSerial_->SetMaxDataCount(454); // 454: number of data points + ECGDataSerial_->SetLineColor(Color::Red()); + ECGDataSerial_->EnableHeadPoint(true); + ECGChart_->AddDataSerial(ECGDataSerial_); + ImageAnimatorCallbackDemo* imageAnimCallback = new ImageAnimatorCallbackDemo(ECGDataSerial_); + ECGAnimator_ = new OHOS::Animator(imageAnimCallback, ECGChart_, 0, true); + AnimatorManager::GetInstance()->Add(ECGAnimator_); + ECGAnimator_->Start(); + + addPointsBtn_ = new UILabelButton(); + smoothBtn_ = new UILabelButton(); + hidePointsBtn_ = new UILabelButton(); + + // 2: half of screen width + positionX_ = Screen::GetInstance().GetWidth() / 2 + VIEW_DISTANCE_TO_LEFT_SIDE; + positionY_ = lastY_ + 10; // 10: increase y-coordinate + SetUpButton(addPointsBtn_, "添加点 "); + + positionX_ = addPointsBtn_->GetX() + addPointsBtn_->GetWidth() + g_blank; + positionY_ = addPointsBtn_->GetY(); + SetUpButton(smoothBtn_, "平滑化 "); + + positionX_ = smoothBtn_->GetX() + smoothBtn_->GetWidth() + g_blank; + positionY_ = smoothBtn_->GetY(); + SetUpButton(hidePointsBtn_, "隐藏点 "); +} + +bool UITestChartPolyline::OnClick(UIView& view, const ClickEvent& event) +{ + UIChartDataSerial::PointStyle pointStyle; + pointStyle.fillColor = Color::White(); + pointStyle.radius = 5; // 5: Inner radius + pointStyle.strokeColor = Color::Red(); + pointStyle.strokeWidth = 2; // 2: border width + + if (&view == addDataSerialBtn_) { + if (curDataIndex_ >= DATA_NUM) { + return true; + } + chart_->AddDataSerial(dataSerial_[curDataIndex_]); + curDataIndex_++; + chart_->Invalidate(); + } else if (&view == deleteDataSerialBtn_) { + if (curDataIndex_ <= 0) { + return true; + } + chart_->DeleteDataSerial(dataSerial_[curDataIndex_ - 1]); + curDataIndex_--; + chart_->Invalidate(); + } else if (&view == clearDataSerialBtn_) { + chart_->ClearDataSerial(); + curDataIndex_ = 0; + chart_->Invalidate(); + } else if (&view == topPointBtn_) { + dataSerial_[0]->EnableTopPoint(true); + pointStyle.strokeColor = Color::Red(); + dataSerial_[0]->SetTopPointStyle(pointStyle); + chart_->Invalidate(); + } else if (&view == bottomPointBtn_) { + dataSerial_[0]->EnableBottomPoint(true); + pointStyle.strokeColor = Color::Blue(); + dataSerial_[0]->SetBottomPointStyle(pointStyle); + chart_->Invalidate(); + } else if (&view == headPointBtn_) { + dataSerial_[0]->EnableHeadPoint(true); + pointStyle.strokeColor = Color::Yellow(); + dataSerial_[0]->SetHeadPointStyle(pointStyle); + chart_->Invalidate(); + } else if (&view == reverseBtn_) { + chart_->EnableReverse(true); + chart_->Invalidate(); + } else { + ClickExpand(view, pointStyle); + } + return true; +} + +bool UITestChartPolyline::ClickExpand(UIView& view, UIChartDataSerial::PointStyle pointStyle) +{ + if (&view == gradientBottomBtn_) { + chart_->SetGradientBottom(50); // 50: bottom of the filling range + chart_->Invalidate(); + } else if (&view == addPointsBtn_) { + g_addPointsFlag = true; + } else if (&view == smoothBtn_) { + ECGDataSerial_->EnableSmooth(true); + ECGChart_->Invalidate(); + } else if (&view == hidePointsBtn_) { + g_hidePointsFlag = true; + } + return true; +} + +void UITestChartPolyline::SetUpButton(UILabelButton* btn, const char* title) +{ + if (btn == nullptr) { + return; + } + container_->Add(btn); + btn->SetPosition(positionX_, positionY_, BUTTON_WIDHT2, BUTTON_HEIGHT2); + positionY_ += btn->GetHeight() + 10; // 10: increase height + btn->SetText(title); + btn->SetFont(DEFAULT_VECTOR_FONT_FILENAME, BUTTON_LABEL_SIZE); + btn->SetOnClickListener(this); + btn->SetStyleForState(STYLE_BORDER_RADIUS, BUTTON_STYLE_BORDER_RADIUS_VALUE, UIButton::RELEASED); + btn->SetStyleForState(STYLE_BORDER_RADIUS, BUTTON_STYLE_BORDER_RADIUS_VALUE, UIButton::PRESSED); + btn->SetStyleForState(STYLE_BORDER_RADIUS, BUTTON_STYLE_BORDER_RADIUS_VALUE, UIButton::INACTIVE); + btn->SetStyleForState(STYLE_BACKGROUND_COLOR, BUTTON_STYLE_BACKGROUND_COLOR_VALUE, UIButton::RELEASED); + btn->SetStyleForState(STYLE_BACKGROUND_COLOR, BUTTON_STYLE_BACKGROUND_COLOR_VALUE, UIButton::PRESSED); + btn->SetStyleForState(STYLE_BACKGROUND_COLOR, BUTTON_STYLE_BACKGROUND_COLOR_VALUE, UIButton::INACTIVE); + container_->Invalidate(); +} + +void UITestChartPolyline::SetLastPos(UIView* view) +{ + if (view == nullptr) { + return; + } + lastX_ = view->GetX(); + lastY_ = view->GetY() + view->GetHeight(); +} +} // namespace OHOS \ No newline at end of file diff --git a/test/uitest/test_chart/ui_test_chart_polyline.h b/test/uitest/test_chart/ui_test_chart_polyline.h new file mode 100755 index 0000000..640499f --- /dev/null +++ b/test/uitest/test_chart/ui_test_chart_polyline.h @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef UI_TEST_CHART_POLYLINE_H +#define UI_TEST_CHART_POLYLINE_H + +#include "components/ui_chart.h" +#include "components/ui_label.h" +#include "components/ui_label_button.h" +#include "components/ui_scroll_view.h" +#include "ui_test.h" + +namespace OHOS { +class UITestChartPolyline : public UITest, public UIView::OnClickListener { +public: + UITestChartPolyline() {} + ~UITestChartPolyline() {} + void SetUp() override; + void TearDown() override; + UIView* GetTestView() override; + + void SetUpButton(UILabelButton* btn, const char* title); + + bool OnClick(UIView& view, const ClickEvent& event) override; + bool ClickExpand(UIView& view, UIChartDataSerial::PointStyle pointStyle); + + void UIKit_ChartPolyline_Test_AddDataSerial_001(); + void UIKit_ChartPolyline_Test_EnableReverse_002(); + void UIKit_ChartPolyline_Test_SetGradientBottom_003(); + void UIKit_ChartPolyline_Test_AddPoints_004(); + +private: + void SetLastPos(UIView* view); + void InnerDeleteChildren(UIView* view) const; + static constexpr uint8_t DATA_NUM = 3; + UIScrollView* container_ = nullptr; + UIChartPolyline* chart_ = nullptr; + UIChartDataSerial *dataSerial_[DATA_NUM] = {0}; + uint8_t curDataIndex_ = 0; + + UIChartPolyline* ECGChart_ = nullptr; + UIChartDataSerial* ECGDataSerial_ = nullptr; + Animator* ECGAnimator_ = nullptr; + + UILabelButton* addDataSerialBtn_ = nullptr; + UILabelButton* deleteDataSerialBtn_ = nullptr; + UILabelButton* clearDataSerialBtn_ = nullptr; + UILabelButton* reverseBtn_ = nullptr; + UILabelButton* topPointBtn_ = nullptr; + UILabelButton* bottomPointBtn_ = nullptr; + UILabelButton* headPointBtn_ = nullptr; + UILabelButton* gradientBottomBtn_ = nullptr; + + UILabelButton* addPointsBtn_ = nullptr; + UILabelButton* smoothBtn_ = nullptr; + UILabelButton* hidePointsBtn_ = nullptr; + + int16_t lastX_ = 0; + int16_t lastY_ = 0; +}; +} // namespace OHOS +#endif // UI_TEST_CHART_POLYLINE_H diff --git a/test/uitest/test_dialog/ui_test_dialog.cpp b/test/uitest/test_dialog/ui_test_dialog.cpp new file mode 100755 index 0000000..c6f222b --- /dev/null +++ b/test/uitest/test_dialog/ui_test_dialog.cpp @@ -0,0 +1,493 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "ui_test_dialog.h" +#include "common/screen.h" +#include "components/ui_dialog.h" +#include "components/ui_label.h" +#include "graphic_config.h" +#include "test_resource_config.h" + +#if ENABLE_WINDOW +namespace OHOS { +namespace { +const int16_t GAP = 5; +const int16_t TITLE_HEIGHT = 20; +const uint16_t LABEL_WIDTH = 350; +const uint16_t LABEL_HEIGHT = 50; +const uint16_t BUTTON_WIDTH = 100; +const uint16_t BUTTON_HEIGHT = 50; +} // namespace + +class TestUIDialogButtonListener : public UIView::OnClickListener { +public: + TestUIDialogButtonListener(UIDialog::DialogButtonType buttonType, UILabel* label) + { + dialog_ = nullptr; + buttonType_ = buttonType; + label_ = label; + } + virtual ~TestUIDialogButtonListener() {} + + void SetDialog(UIDialog** dialog) + { + dialog_ = dialog; + } + + bool OnClick(UIView &view, const ClickEvent& event) override + { + switch (buttonType_) { + case UIDialog::DialogButtonType::BUTTON_LEFT: + label_->SetText("button left click!"); + break; + case UIDialog::DialogButtonType::BUTTON_MID: + label_->SetText("button mid click!"); + break; + case UIDialog::DialogButtonType::BUTTON_RIGHT: + label_->SetText("button right click!"); + break; + default: + break; + } + if (*dialog_ != nullptr) { + delete *dialog_; + *dialog_ = nullptr; + } + return true; + } + +private: + UIDialog** dialog_; + UIDialog::DialogButtonType buttonType_; + UILabel* label_; +}; + +class TestUIDialogOnCancelListener : public UIView::OnClickListener { +public: + TestUIDialogOnCancelListener(UILabel* label) + { + dialog_ = nullptr; + label_ = label; + } + virtual ~TestUIDialogOnCancelListener() {} + + void SetDialog(UIDialog** dialog) + { + dialog_ = dialog; + } + + bool OnClick(UIView &view, const ClickEvent& event) override + { + label_->SetText("Click outside the dialog."); + if (*dialog_ != nullptr) { + delete *dialog_; + *dialog_ = nullptr; + } + return true; + } + +private: + UIDialog** dialog_; + UILabel* label_; +}; + +void UITestDialog::SetUp() +{ + if (container_ == nullptr) { + container_ = new UIScrollView(); + container_->SetThrowDrag(true); + container_->SetHorizontalScrollState(false); + container_->Resize(Screen::GetInstance().GetWidth(), Screen::GetInstance().GetHeight() - LABEL_HEIGHT); + positionX_ = 50; // 50: init position x0 + positionY_ = 5; // 5: init position y + } + + if (label_ == nullptr) { + label_ = new UILabel(); + label_->SetPosition(0, positionY_); + label_->Resize(LABEL_WIDTH, LABEL_HEIGHT); + label_->SetFont(DEFAULT_VECTOR_FONT_FILENAME, 18); // 18: font size + label_->SetText("label"); + container_->Add(label_); + positionY_ += LABEL_HEIGHT + GAP; + } + if (listener1_ == nullptr) { + listener1_ = new TestUIDialogButtonListener(UIDialog::DialogButtonType::BUTTON_LEFT, label_); + } + if (listener2_ == nullptr) { + listener2_ = new TestUIDialogButtonListener(UIDialog::DialogButtonType::BUTTON_MID, label_); + } + if (listener3_ == nullptr) { + listener3_ = new TestUIDialogButtonListener(UIDialog::DialogButtonType::BUTTON_RIGHT, label_); + } + if (listener_ == nullptr) { + listener_ = new TestUIDialogOnCancelListener(label_); + } +} + +void UITestDialog::TearDown() +{ + DeleteChildren(container_); + if (listener1_ != nullptr) { + delete listener1_; + listener1_ = nullptr; + } + if (listener2_ != nullptr) { + delete listener2_; + listener2_ = nullptr; + } + if (listener3_ != nullptr) { + delete listener3_; + listener3_ = nullptr; + } + if (listener_ != nullptr) { + delete listener_; + listener_ = nullptr; + } + if (dialog_ != nullptr) { + delete dialog_; + dialog_ = nullptr; + } + label_ = nullptr; + container_ = nullptr; +} + +void UITestDialog::InnerTestTitle(const char* title) +{ + UILabel* titleLabel = new UILabel(); + titleLabel->SetPosition(0, positionY_, Screen::GetInstance().GetWidth(), TITLE_HEIGHT); + titleLabel->SetStyle(STYLE_TEXT_COLOR, Color::Black().full); + titleLabel->SetStyle(STYLE_BACKGROUND_COLOR, Color::White().full); + titleLabel->SetStyle(STYLE_BACKGROUND_OPA, OPA_OPAQUE); + titleLabel->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); + titleLabel->SetText(title); + + container_->Add(titleLabel); + positionY_ += TITLE_HEIGHT + GAP; +} + +UIView* UITestDialog::GetTestView() +{ + UIKitDialogTest001(); + UIKitDialogTest002(); + UIKitDialogTest003(); + UIKitDialogTest004(); + UIKitDialogTest005(); + UIKitDialogTest006(); + UIKitDialogTest007(); + UIKitDialogTest008(); + UIKitDialogTest009(); + UIKitDialogTest010(); + return container_; +} + +void UITestDialog::UIKitDialogTest001() +{ + if (container_ == nullptr) { + return; + } + InnerTestTitle("测试设置较长标题、较短正文、单个较短按钮"); + button1_ = new UILabelButton(); + button1_->SetPosition(0, positionY_, BUTTON_WIDTH, BUTTON_HEIGHT); + button1_->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); + button1_->SetText("Dialog1"); + button1_->SetOnClickListener(this); + container_->Add(button1_); + positionY_ += BUTTON_HEIGHT + GAP; +} + +void UITestDialog::UIKitDialogTest002() +{ + if (container_ == nullptr) { + return; + } + InnerTestTitle("测试设置较短标题、较长正文、两个较短按钮"); + button2_ = new UILabelButton(); + button2_->SetPosition(0, positionY_, BUTTON_WIDTH, BUTTON_HEIGHT); + button2_->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); + button2_->SetText("Dialog2"); + button2_->SetOnClickListener(this); + container_->Add(button2_); + positionY_ += BUTTON_HEIGHT + GAP; +} + +void UITestDialog::UIKitDialogTest003() +{ + if (container_ == nullptr) { + return; + } + InnerTestTitle("测试设置较短标题、较短正文、单个较长按钮"); + button3_ = new UILabelButton(); + button3_->SetPosition(0, positionY_, BUTTON_WIDTH, BUTTON_HEIGHT); + button3_->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); + button3_->SetText("Dialog3"); + button3_->SetOnClickListener(this); + container_->Add(button3_); + positionY_ += BUTTON_HEIGHT + GAP; +} + +void UITestDialog::UIKitDialogTest004() +{ + if (container_ == nullptr) { + return; + } + InnerTestTitle("测试设置较短标题、较短正文、三个长按钮"); + button4_ = new UILabelButton(); + button4_->SetPosition(0, positionY_, BUTTON_WIDTH, BUTTON_HEIGHT); + button4_->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); + button4_->SetText("Dialog4"); + button4_->SetOnClickListener(this); + container_->Add(button4_); + positionY_ += BUTTON_HEIGHT + GAP; +} + +void UITestDialog::UIKitDialogTest005() +{ + if (container_ == nullptr) { + return; + } + InnerTestTitle("测试设置较短正文、自动关闭、弹框外点击事件监听"); + button5_ = new UILabelButton(); + button5_->SetPosition(0, positionY_, BUTTON_WIDTH, BUTTON_HEIGHT); + button5_->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); + button5_->SetText("Dialog5"); + button5_->SetOnClickListener(this); + container_->Add(button5_); + positionY_ += BUTTON_HEIGHT + GAP; +} + +void UITestDialog::UIKitDialogTest006() +{ + if (container_ == nullptr) { + return; + } + InnerTestTitle("测试只设置较长正文,点击弹框外自动关闭"); + button6_ = new UILabelButton(); + button6_->SetPosition(0, positionY_, BUTTON_WIDTH, BUTTON_HEIGHT); + button6_->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); + button6_->SetText("Dialog6"); + button6_->SetOnClickListener(this); + container_->Add(button6_); + positionY_ += BUTTON_HEIGHT + GAP; +} + +void UITestDialog::UIKitDialogTest007() +{ + if (container_ == nullptr) { + return; + } + InnerTestTitle("测试设置长标题,长正文,三个长按钮"); + button7_ = new UILabelButton(); + button7_->SetPosition(0, positionY_, BUTTON_WIDTH, BUTTON_HEIGHT); + button7_->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); + button7_->SetText("Dialog7"); + button7_->SetOnClickListener(this); + container_->Add(button7_); + positionY_ += BUTTON_HEIGHT + GAP; +} + +void UITestDialog::UIKitDialogTest008() +{ + if (container_ == nullptr) { + return; + } + InnerTestTitle("测试设置按钮颜色不带透明度"); + button8_ = new UILabelButton(); + button8_->SetPosition(0, positionY_, BUTTON_WIDTH, BUTTON_HEIGHT); + button8_->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); + button8_->SetText("Dialog8"); + button8_->SetOnClickListener(this); + container_->Add(button8_); + positionY_ += BUTTON_HEIGHT + GAP; +} + +void UITestDialog::UIKitDialogTest009() +{ + if (container_ == nullptr) { + return; + } + InnerTestTitle("测试设置按钮颜色带透明度"); + button9_ = new UILabelButton(); + button9_->SetPosition(0, positionY_, BUTTON_WIDTH, BUTTON_HEIGHT); + button9_->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); + button9_->SetText("Dialog9"); + button9_->SetOnClickListener(this); + container_->Add(button9_); + positionY_ += BUTTON_HEIGHT + GAP; +} + +void UITestDialog::UIKitDialogTest010() +{ + if (container_ == nullptr) { + return; + } + InnerTestTitle("测试连续多次设置标题、正文、按钮"); + button10_ = new UILabelButton(); + button10_->SetPosition(0, positionY_, BUTTON_WIDTH, BUTTON_HEIGHT); + button10_->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); + button10_->SetText("Dialog10"); + button10_->SetOnClickListener(this); + container_->Add(button10_); + positionY_ += BUTTON_HEIGHT + GAP; +} + +bool UITestDialog::OnClick(UIView &view, const ClickEvent& event) +{ + if (&view == button1_) { + if (dialog_ != nullptr) { + delete dialog_; + dialog_ = nullptr; + } + dialog_ = new UIDialog(); + dialog_->SetTitle("标题标题标题标题标题"); + dialog_->SetText("段落文本"); + listener1_->SetDialog(&dialog_); + dialog_->SetButton(UIDialog::DialogButtonType::BUTTON_LEFT, "Button1", listener1_); + dialog_->Show(); + } else if (&view == button2_) { + if (dialog_ != nullptr) { + delete dialog_; + dialog_ = nullptr; + } + dialog_ = new UIDialog(); + dialog_->SetTitle("标题"); + dialog_->SetText("段落文本段落文本段落文本段落文本段落文本段落文本段落文本"); + listener1_->SetDialog(&dialog_); + listener3_->SetDialog(&dialog_); + dialog_->SetButton(UIDialog::DialogButtonType::BUTTON_LEFT, "Button1", listener1_); + dialog_->SetButton(UIDialog::DialogButtonType::BUTTON_RIGHT, "Button2", listener3_); + dialog_->Show(); + } else if (&view == button3_) { + if (dialog_ != nullptr) { + delete dialog_; + dialog_ = nullptr; + } + dialog_ = new UIDialog(); + dialog_->SetTitle("标题"); + dialog_->SetText("段落文本"); + listener2_->SetDialog(&dialog_); + dialog_->SetButton(UIDialog::DialogButtonType::BUTTON_MID, "Button1Button1Button1Button1", listener2_); + dialog_->Show(); + } else if (&view == button4_) { + if (dialog_ != nullptr) { + delete dialog_; + dialog_ = nullptr; + } + dialog_ = new UIDialog(); + dialog_->SetTitle("标题"); + dialog_->SetText("段落文本"); + listener1_->SetDialog(&dialog_); + listener2_->SetDialog(&dialog_); + listener3_->SetDialog(&dialog_); + dialog_->SetButton(UIDialog::DialogButtonType::BUTTON_LEFT, "Button111111111111111111", listener1_); + dialog_->SetButton(UIDialog::DialogButtonType::BUTTON_MID, "Button22222222222222222", listener2_); + dialog_->SetButton(UIDialog::DialogButtonType::BUTTON_RIGHT, "Button33333333333333333", listener3_); + dialog_->Show(); + } else if (&view == button5_) { + if (dialog_ != nullptr) { + delete dialog_; + dialog_ = nullptr; + } + dialog_ = new UIDialog(); + dialog_->SetText("段落文本"); + dialog_->EnableAutoCancel(true); + listener_->SetDialog(&dialog_); + dialog_->SetOnCancelListener(listener_); + dialog_->Show(); + } else { + return ClickExpand(view, event); + } + return true; +} + +bool UITestDialog::ClickExpand(UIView &view, const ClickEvent& event) +{ + if (&view == button6_) { + if (dialog_ != nullptr) { + delete dialog_; + dialog_ = nullptr; + } + dialog_ = new UIDialog(); + dialog_->SetText("段落文本段落文本段落文本段落文本段落文本段落文本段落文本段落文本段落文本段落文本"); + dialog_->EnableAutoCancel(true); + listener_->SetDialog(&dialog_); + dialog_->SetOnCancelListener(listener_); + dialog_->Show(); + } else if (&view == button7_) { + if (dialog_ != nullptr) { + delete dialog_; + dialog_ = nullptr; + } + dialog_ = new UIDialog(); + dialog_->SetTitle("段落文本段落文本段落文本段落文本段落文本段落文本段落文本段落文本段落文本段落文本段落文本"); + dialog_->SetText( + "段落文本段落文本段落文本段落文本段落文本段落文本段落文本段落文本段落文本段落文本 \ + 段落文本段落文本段落文本段落文本段落文本段落文本段落文本段落文本段落文本段落文本段落文本段落文本段落文本 \ + 段落文本段落文本段落文本段落文本段落文本段落文本段落文本段落文本段落文本段落文本段落文本 \ + 段落文本段落文本段落文本段落文本段落文本段落文本段落文本段落文本段落文本段落文本段落文本 \ + 段落文本段落文本段落文本段落文本段落文本段落文本段落文本段落文本段落文本段落文本段落文本 \ + 段落文本段落文本段落文本段落文本段落文本段落文本段落文本段落文本段落文本段落文本段落文本段落文本段落文本段落文本段落文本 \ + 段落文本段落文本段落文本段落文本段落文本段落文本段落文本段落文本段落文本段落文本段落文本段落文本段落文本段落文本段落文 \ + 段落文本段落文本段落文本段落文本段落文本段落文本段落文本段落文本段落文本段落文本段落文本段落文本段落文本段落文本段落文"); + listener1_->SetDialog(&dialog_); + listener2_->SetDialog(&dialog_); + listener3_->SetDialog(&dialog_); + dialog_->SetButton(UIDialog::DialogButtonType::BUTTON_LEFT, "Button111111111111111111111", listener1_); + dialog_->SetButton(UIDialog::DialogButtonType::BUTTON_MID, "Button22222222222222222222", listener2_); + dialog_->SetButton(UIDialog::DialogButtonType::BUTTON_RIGHT, "Button33333333333333333333", listener3_); + dialog_->Show(); + } else if (&view == button8_) { + if (dialog_ != nullptr) { + delete dialog_; + dialog_ = nullptr; + } + dialog_ = new UIDialog(); + dialog_->SetText("段落正文"); + listener2_->SetDialog(&dialog_); + dialog_->SetButton(UIDialog::DialogButtonType::BUTTON_MID, "button", listener2_); + dialog_->SetButtonColor(UIDialog::DialogButtonType::BUTTON_MID, Color::Red()); + dialog_->Show(); + } else if (&view == button9_) { + if (dialog_ != nullptr) { + delete dialog_; + dialog_ = nullptr; + } + dialog_ = new UIDialog(); + dialog_->SetText("段落正文"); + listener2_->SetDialog(&dialog_); + dialog_->SetButton(UIDialog::DialogButtonType::BUTTON_MID, "button", listener2_); + // 0xFF, 0x00, 0x00, 0x7F: color red with 50% opacity + ColorType color = Color::GetColorFromRGBA(0xFF, 0x00, 0x00, 0x7F); + dialog_->SetButtonColor(UIDialog::DialogButtonType::BUTTON_MID, color); + dialog_->Show(); + } else if (&view == button10_) { + if (dialog_ != nullptr) { + delete dialog_; + dialog_ = nullptr; + } + dialog_ = new UIDialog(); + dialog_->SetTitle("标题1"); + dialog_->SetText("段落正文1"); + listener2_->SetDialog(&dialog_); + dialog_->SetButton(UIDialog::DialogButtonType::BUTTON_MID, "按钮1", listener2_); + dialog_->SetTitle("标题2"); + dialog_->SetText("段落正文2"); + dialog_->SetButton(UIDialog::DialogButtonType::BUTTON_MID, "按钮2", listener2_); + dialog_->Show(); + } + return true; +} +} // namespace OHOS +#endif // ENABLE_WINDOW \ No newline at end of file diff --git a/test/uitest/test_dialog/ui_test_dialog.h b/test/uitest/test_dialog/ui_test_dialog.h new file mode 100755 index 0000000..19f6c83 --- /dev/null +++ b/test/uitest/test_dialog/ui_test_dialog.h @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ +#ifndef UI_TEST_DIALOG_H +#define UI_TEST_DIALOG_H + +#include "components/ui_dialog.h" +#include "components/ui_scroll_view.h" +#include "graphic_config.h" +#include "ui_test.h" + +#if ENABLE_WINDOW +namespace OHOS { +class TestUIDialogButtonListener; +class TestUIDialogOnCancelListener; + +class UITestDialog : public UITest, public UIView::OnClickListener { +public: + UITestDialog() {} + ~UITestDialog() {} + void SetUp() override; + void TearDown() override; + void InnerTestTitle(const char* title); + UIView* GetTestView() override; + + bool OnClick(UIView &view, const ClickEvent& event) override; + bool ClickExpand(UIView &view, const ClickEvent& event); + + void UIKitDialogTest001(); + void UIKitDialogTest002(); + void UIKitDialogTest003(); + void UIKitDialogTest004(); + void UIKitDialogTest005(); + void UIKitDialogTest006(); + void UIKitDialogTest007(); + void UIKitDialogTest008(); + void UIKitDialogTest009(); + void UIKitDialogTest010(); + +private: + UIScrollView* container_ = nullptr; + UILabel* label_ = nullptr; + UILabelButton* button1_ = nullptr; + UILabelButton* button2_ = nullptr; + UILabelButton* button3_ = nullptr; + UILabelButton* button4_ = nullptr; + UILabelButton* button5_ = nullptr; + UILabelButton* button6_ = nullptr; + UILabelButton* button7_ = nullptr; + UILabelButton* button8_ = nullptr; + UILabelButton* button9_ = nullptr; + UILabelButton* button10_ = nullptr; + UIDialog* dialog_ = nullptr; + TestUIDialogButtonListener* listener1_ = nullptr; + TestUIDialogButtonListener* listener2_ = nullptr; + TestUIDialogButtonListener* listener3_ = nullptr; + TestUIDialogOnCancelListener* listener_ = nullptr; +}; +} // namespace OHOS +#endif // UI_TEST_DIALOG_H +#endif // ENABLE_WINDOW \ No newline at end of file diff --git a/test/uitest/test_digital_clock/ui_test_digital_clock.cpp b/test/uitest/test_digital_clock/ui_test_digital_clock.cpp new file mode 100755 index 0000000..16ac898 --- /dev/null +++ b/test/uitest/test_digital_clock/ui_test_digital_clock.cpp @@ -0,0 +1,214 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "ui_test_digital_clock.h" +#include "common/screen.h" +#include "components/ui_digital_clock.h" +#include "components/ui_label.h" +#include "font/ui_font.h" + +namespace OHOS { +namespace { +const int16_t GAP = 10; +const int16_t TITLE_HEIGHT = 30; +const uint16_t DIGITAL_CLOCK_WIDTH = 350; +const uint16_t DIGITAL_CLOCK_HEIGHT = 50; +} // namespace + +void UITestDigitalClock::SetUp() +{ + if (container_ == nullptr) { + container_ = new UIScrollView(); + container_->SetThrowDrag(true); + container_->SetHorizontalScrollState(false); + container_->Resize(Screen::GetInstance().GetWidth(), Screen::GetInstance().GetHeight() - BACK_BUTTON_HEIGHT); + positionX_ = 50; // 50: init position x + positionY_ = 5; // 5: init position y + } +} + +void UITestDigitalClock::TearDown() +{ + UIView* view = static_cast(container_)->GetChildrenHead(); + while (view != nullptr) { + UIView* tempView = view; + view = view->GetNextSibling(); + if (tempView->GetParent()) { + static_cast(tempView->GetParent())->Remove(tempView); + } + delete tempView; + } + delete container_; + container_ = nullptr; +} + +void UITestDigitalClock::InnerTestTitle(const char* title) +{ + UILabel* titleLabel = new UILabel(); + titleLabel->SetPosition(TEXT_DISTANCE_TO_LEFT_SIDE, positionY_, Screen::GetInstance().GetWidth(), + TITLE_LABEL_DEFAULT_HEIGHT); + titleLabel->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); + titleLabel->SetText(title); + container_->Add(titleLabel); + positionY_ += TITLE_HEIGHT + GAP; +} + +UIView* UITestDigitalClock::GetTestView() +{ + UIKit_UIDigitalClock_Test_Display_001(); + UIKit_UIDigitalClock_Test_Display_002(); + UIKit_UIDigitalClock_Test_SetColor(); + UIKit_UIDigitalClock_Test_DisplayMode_001(); + UIKit_UIDigitalClock_Test_DisplayMode_002(); + UIKit_UIDigitalClock_Test_DisplayMode_003(); + UIKit_UIDigitalClock_Test_DisplayMode_004(); + UIKit_UIDigitalClock_Test_DisplayLeadingZero(); + UIKit_UIDigitalClock_Test_SetOpacity(); + return container_; +} + +void UITestDigitalClock::UIKit_UIDigitalClock_Test_Display_001() +{ + if (container_ != nullptr) { + InnerTestTitle("UIDigitalClock效果"); + UIDigitalClock* dClock = new UIDigitalClock(); + dClock->SetPosition(positionX_, positionY_); + dClock->Resize(DIGITAL_CLOCK_WIDTH, DIGITAL_CLOCK_HEIGHT); + dClock->SetFont(DEFAULT_VECTOR_FONT_FILENAME, 30); // 30: font size + dClock->SetTime24Hour(7, 25, 50); // 7: hour, 25: minute, 50: second + container_->Add(dClock); + positionY_ += DIGITAL_CLOCK_HEIGHT + GAP; + } +} + +void UITestDigitalClock::UIKit_UIDigitalClock_Test_Display_002() +{ + if (container_ != nullptr) { + InnerTestTitle("UIDigitalClock效果"); + UIDigitalClock* dClock = new UIDigitalClock(); + dClock->SetPosition(positionX_, positionY_); + dClock->Resize(DIGITAL_CLOCK_WIDTH, DIGITAL_CLOCK_HEIGHT); + dClock->SetFont(DEFAULT_VECTOR_FONT_FILENAME, 30); // 30: font size + dClock->SetTime24Hour(7, 25, 50); // 7:hour, 25:minute, 50:second + container_->Add(dClock); + positionY_ += DIGITAL_CLOCK_HEIGHT + GAP; + } +} + +void UITestDigitalClock::UIKit_UIDigitalClock_Test_SetColor() +{ + if (container_ != nullptr) { + InnerTestTitle("设置Digital Clock颜色"); + UIDigitalClock* dClock = new UIDigitalClock(); + dClock->SetPosition(positionX_, positionY_); + dClock->Resize(DIGITAL_CLOCK_WIDTH, DIGITAL_CLOCK_HEIGHT); + dClock->SetFont(DEFAULT_VECTOR_FONT_FILENAME, 30); // 30: font size + dClock->SetTime24Hour(7, 25, 50); // 7:hour, 25:minute, 50:second + dClock->SetColor(Color::Red()); + container_->Add(dClock); + positionY_ += DIGITAL_CLOCK_HEIGHT + GAP; + } +} + +void UITestDigitalClock::UIKit_UIDigitalClock_Test_DisplayMode_001() +{ + if (container_ != nullptr) { + InnerTestTitle("设置Digital Clock仅显示小时、分钟 "); + UIDigitalClock* dClock = new UIDigitalClock(); + dClock->SetPosition(positionX_, positionY_); + dClock->Resize(DIGITAL_CLOCK_WIDTH, DIGITAL_CLOCK_HEIGHT); + dClock->SetFont(DEFAULT_VECTOR_FONT_FILENAME, 30); // 30: font size + dClock->SetTime24Hour(17, 25, 50); // 17:hour, 25:minute, 50:second + dClock->SetDisplayMode(UIDigitalClock::DISPLAY_12_HOUR_NO_SECONDS); + container_->Add(dClock); + positionY_ += DIGITAL_CLOCK_HEIGHT + GAP; + } +} + +void UITestDigitalClock::UIKit_UIDigitalClock_Test_DisplayMode_002() +{ + if (container_ != nullptr) { + InnerTestTitle("设置Digital Clock 24小时制仅显示小时、分钟 "); + UIDigitalClock* dClock = new UIDigitalClock(); + dClock->SetPosition(positionX_, positionY_); + dClock->Resize(DIGITAL_CLOCK_WIDTH, DIGITAL_CLOCK_HEIGHT); + dClock->SetFont(DEFAULT_VECTOR_FONT_FILENAME, 30); // 30: font size + dClock->SetTime24Hour(17, 25, 50); // 17:hour, 25:minute, 50:second + dClock->SetDisplayMode(UIDigitalClock::DISPLAY_24_HOUR_NO_SECONDS); + container_->Add(dClock); + positionY_ += DIGITAL_CLOCK_HEIGHT + GAP; + } +} + +void UITestDigitalClock::UIKit_UIDigitalClock_Test_DisplayMode_003() +{ + if (container_ != nullptr) { + InnerTestTitle("设置Digital Clock 12小时制 "); + UIDigitalClock* dClock = new UIDigitalClock(); + dClock->SetPosition(positionX_, positionY_); + dClock->Resize(DIGITAL_CLOCK_WIDTH, DIGITAL_CLOCK_HEIGHT); + dClock->SetFont(DEFAULT_VECTOR_FONT_FILENAME, 30); // 30: font size + dClock->SetTime24Hour(17, 25, 50); // 17:hour, 25:minute, 50:second + dClock->SetDisplayMode(UIDigitalClock::DISPLAY_12_HOUR); + container_->Add(dClock); + positionY_ += DIGITAL_CLOCK_HEIGHT + GAP; + } +} + +void UITestDigitalClock::UIKit_UIDigitalClock_Test_DisplayMode_004() +{ + if (container_ != nullptr) { + InnerTestTitle("设置Digital Clock 24小时制 "); + UIDigitalClock* dClock = new UIDigitalClock(); + dClock->SetPosition(positionX_, positionY_); + dClock->Resize(DIGITAL_CLOCK_WIDTH, DIGITAL_CLOCK_HEIGHT); + dClock->SetFont(DEFAULT_VECTOR_FONT_FILENAME, 30); // 30: font size + dClock->SetTime24Hour(17, 25, 50); // 17:hour, 25:minute, 50:second + dClock->SetDisplayMode(UIDigitalClock::DISPLAY_24_HOUR); + container_->Add(dClock); + positionY_ += DIGITAL_CLOCK_HEIGHT + GAP; + } +} + +void UITestDigitalClock::UIKit_UIDigitalClock_Test_DisplayLeadingZero() +{ + if (container_ != nullptr) { + InnerTestTitle("设置Digital Clock不显示首位的0 "); + UIDigitalClock* dClock = new UIDigitalClock(); + dClock->SetPosition(positionX_, positionY_); + dClock->Resize(DIGITAL_CLOCK_WIDTH, DIGITAL_CLOCK_HEIGHT); + dClock->SetFont(DEFAULT_VECTOR_FONT_FILENAME, 30); // 30: font size + dClock->SetTime24Hour(7, 5, 9); // 7:hour, 5:minute, 9:second + dClock->DisplayLeadingZero(false); + container_->Add(dClock); + positionY_ += DIGITAL_CLOCK_HEIGHT + GAP; + } +} + +void UITestDigitalClock::UIKit_UIDigitalClock_Test_SetOpacity() +{ + if (container_ != nullptr) { + InnerTestTitle("设置Digital Clock透明度 "); + UIDigitalClock* dClock = new UIDigitalClock(); + dClock->SetPosition(positionX_, positionY_); + dClock->Resize(DIGITAL_CLOCK_WIDTH, DIGITAL_CLOCK_HEIGHT); + dClock->SetFont(DEFAULT_VECTOR_FONT_FILENAME, 30); // 30: font size + dClock->SetTime24Hour(7, 5, 9); // 7:hour, 5:minute, 9:second + dClock->SetOpacity(178); // 178: num of opacity + container_->Add(dClock); + positionY_ += DIGITAL_CLOCK_HEIGHT + GAP; + } +} +} // namespace OHOS \ No newline at end of file diff --git a/test/uitest/test_digital_clock/ui_test_digital_clock.h b/test/uitest/test_digital_clock/ui_test_digital_clock.h new file mode 100755 index 0000000..72a1813 --- /dev/null +++ b/test/uitest/test_digital_clock/ui_test_digital_clock.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef UI_TEST_DIGITAL_CLOCK_H +#define UI_TEST_DIGITAL_CLOCK_H + +#include "components/ui_scroll_view.h" +#include "font/ui_font.h" +#include "ui_test.h" + +namespace OHOS { +class UITestDigitalClock : public UITest { +public: + UITestDigitalClock() {} + ~UITestDigitalClock() {} + void SetUp() override; + void TearDown() override; + UIView* GetTestView() override; + + void UIKit_UIDigitalClock_Test_Display_001(); + void UIKit_UIDigitalClock_Test_Display_002(); + void UIKit_UIDigitalClock_Test_SetColor(); + void UIKit_UIDigitalClock_Test_DisplayMode_001(); + void UIKit_UIDigitalClock_Test_DisplayMode_002(); + void UIKit_UIDigitalClock_Test_DisplayMode_003(); + void UIKit_UIDigitalClock_Test_DisplayMode_004(); + void UIKit_UIDigitalClock_Test_DisplayLeadingZero(); + void UIKit_UIDigitalClock_Test_SetOpacity(); + +private: + UIScrollView* container_ = nullptr; + void InnerTestTitle(const char* title); +}; +} // namespace OHOS +#endif // UI_TEST_DIGITAL_CLOCK_H diff --git a/test/uitest/test_draw_line/ui_test_draw_line.cpp b/test/uitest/test_draw_line/ui_test_draw_line.cpp new file mode 100755 index 0000000..aff37b8 --- /dev/null +++ b/test/uitest/test_draw_line/ui_test_draw_line.cpp @@ -0,0 +1,398 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "ui_test_draw_line.h" +#include "common/screen.h" +#include "components/ui_canvas.h" +#include "components/ui_label.h" +#include "components/ui_label_button.h" + +namespace OHOS { +namespace { +const uint16_t DELTA_X = 24; +} + +void UITestDrawLine::SetUp() +{ + if (container_ == nullptr) { + container_ = new UIScrollView(); + container_->Resize(Screen::GetInstance().GetWidth(), Screen::GetInstance().GetHeight() - BACK_BUTTON_HEIGHT); + container_->SetHorizontalScrollState(false); + } +} + +void UITestDrawLine::TearDown() +{ + DeleteChildren(container_); + container_ = nullptr; +} + +UIView* UITestDrawLine::GetTestView() +{ + UIKit_Draw_Line_Test_Line_001(); + UIKit_Draw_Line_Test_Line_002(); + UIKit_Draw_Line_Test_Line_003(); + UIKit_Draw_Line_Test_Line_004(); + UIKit_Draw_Line_Test_Line_005(); + UIKit_Draw_Line_Test_Line_006(); + UIKit_Draw_Line_Test_Line_007(); + UIKit_Draw_Line_Test_Line_008(); + UIKit_Draw_Line_Test_Line_009(); + UIKit_Draw_Line_Test_Line_010(); + UIKit_Draw_Line_Test_Line_011(); + UIKit_Draw_Line_Test_Line_012(); + return container_; +} + +UIViewGroup* UITestDrawLine::CreateTestCaseGroup() const +{ + UIViewGroup* group = new UIViewGroup(); + // 288: group width; 250: group height + group->Resize(288, 250); + return group; +} + +UILabel* UITestDrawLine::CreateTitleLabel() const +{ + UILabel* label = new UILabel(); + // 2: half of screen width; + label->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE, TEXT_DISTANCE_TO_TOP_SIDE, Screen::GetInstance().GetWidth() / 2, + TITLE_LABEL_DEFAULT_HEIGHT); + label->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); + return label; +} + +UICanvas* UITestDrawLine::CreateCanvas() const +{ + UICanvas* canvas = new UICanvas(); + canvas->SetHeight(200); // 200 : height size + canvas->SetWidth(200); // 200 : width size + canvas->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE, VIEW_DISTANCE_TO_TOP_SIDE); + canvas->SetStyle(STYLE_BACKGROUND_COLOR, Color::Gray().full); + return canvas; +} + +void UITestDrawLine::UIKit_Draw_Line_Test_Line_001() +{ + if (container_ == nullptr) { + return; + } + + UIViewGroup* group = CreateTestCaseGroup(); + group->SetViewId("UIKit_Draw_Line_Test_Line_001"); + group->SetPosition(0, 0); + + UILabel* label = CreateTitleLabel(); + group->Add(label); + label->SetText("水平直线绘制 "); + + UICanvas* canvas = CreateCanvas(); + Paint paint; + canvas->DrawLine({50, 50}, {150, 50}, paint); // 50 : start x 50 : start y 150 : end x 50 : end y + group->Add(canvas); + + container_->Add(group); +} + +void UITestDrawLine::UIKit_Draw_Line_Test_Line_002() +{ + if (container_ == nullptr) { + return; + } + + UIViewGroup* group = CreateTestCaseGroup(); + group->SetViewId("UIKit_Draw_Line_Test_Line_002"); + group->SetPosition(0, 0); + + UILabel* label = CreateTitleLabel(); + group->Add(label); + label->SetText("垂直直线绘制 "); + + UICanvas* canvas = CreateCanvas(); + Paint paint; + canvas->DrawLine({100, 50}, {100, 150}, paint); // 100 : start x 50 : start y 100 : end x 150 : end y + group->Add(canvas); + + container_->Add(group); + group->LayoutRightToSibling("UIKit_Draw_Line_Test_Line_001", DELTA_X); +} + +void UITestDrawLine::UIKit_Draw_Line_Test_Line_003() +{ + if (container_ == nullptr) { + return; + } + + UIViewGroup* group = CreateTestCaseGroup(); + group->SetViewId("UIKit_Draw_Line_Test_Line_003"); + group->SetPosition(0, 0); + + UILabel* label = CreateTitleLabel(); + group->Add(label); + label->SetText("左下-右上方向直线绘制 "); + + UICanvas* canvas = CreateCanvas(); + Paint paint; + canvas->DrawLine({20, 180}, {160, 20}, paint); // 20 : start x 180 : start y 160 : end x 20 : end y + canvas->DrawLine({20, 180}, {180, 20}, paint); // 20 : start x 180 : start y 180 : end x 20 : end y + canvas->DrawLine({20, 180}, {180, 40}, paint); // 20 : start x 180 : start y 180 : end x 40 : end y + group->Add(canvas); + + container_->Add(group); + group->LayoutRightToSibling("UIKit_Draw_Line_Test_Line_002", DELTA_X); +} + +void UITestDrawLine::UIKit_Draw_Line_Test_Line_004() +{ + if (container_ == nullptr) { + return; + } + + UIViewGroup* group = CreateTestCaseGroup(); + group->SetViewId("UIKit_Draw_Line_Test_Line_004"); + group->SetPosition(0, 0); + + UILabel* label = CreateTitleLabel(); + group->Add(label); + label->SetText("左上-右下方向直线绘制 "); + + UICanvas* canvas = CreateCanvas(); + Paint paint; + canvas->DrawLine({20, 20}, {160, 180}, paint); // 20 : start x 20 : start y 160 : end x 180 : end y + canvas->DrawLine({20, 20}, {180, 180}, paint); // 20 : start x 20 : start y 180 : end x 180 : end y + canvas->DrawLine({20, 20}, {180, 160}, paint); // 20 : start x 20 : start y 180 : end x 160 : end y + group->Add(canvas); + + container_->Add(group); + group->LayoutBottomToSibling("UIKit_Draw_Line_Test_Line_001", 10); // 10 : offset size +} + +void UITestDrawLine::UIKit_Draw_Line_Test_Line_005() +{ + if (container_ == nullptr) { + return; + } + + UIViewGroup* group = CreateTestCaseGroup(); + group->SetViewId("UIKit_Draw_Line_Test_Line_005"); + group->SetPosition(0, 0); + + UILabel* label = CreateTitleLabel(); + group->Add(label); + label->SetText("右上-左下方向直线绘制 "); + + UICanvas* canvas = CreateCanvas(); + Paint paint; + canvas->DrawLine({180, 20}, {20, 160}, paint); // 180 : start x 20 : start y 20 : end x 160 : end y + canvas->DrawLine({180, 20}, {20, 180}, paint); // 180 : start x 20 : start y 20 : end x 180 : end y + canvas->DrawLine({180, 20}, {40, 180}, paint); // 180 : start x 20 : start y 40 : end x 180 : end y + group->Add(canvas); + + container_->Add(group); + group->LayoutBottomToSibling("UIKit_Draw_Line_Test_Line_002", 10); // 10: offset + group->LayoutRightToSibling("UIKit_Draw_Line_Test_Line_004", DELTA_X); +} + +void UITestDrawLine::UIKit_Draw_Line_Test_Line_006() +{ + if (container_ == nullptr) { + return; + } + + UIViewGroup* group = CreateTestCaseGroup(); + group->SetViewId("UIKit_Draw_Line_Test_Line_006"); + group->SetPosition(0, 0); + + UILabel* label = CreateTitleLabel(); + group->Add(label); + label->SetText("左上-右下方向直线绘制 "); + + UICanvas* canvas = CreateCanvas(); + Paint paint; + canvas->DrawLine({180, 180}, {20, 40}, paint); // 180 : start x 180 : start y 20 : end x 40 : end y + canvas->DrawLine({180, 180}, {20, 20}, paint); // 180 : start x 180 : start y 20 : end x 20 : end y + canvas->DrawLine({180, 180}, {40, 20}, paint); // 180 : start x 180 : start y 40 : end x 20 : end y + group->Add(canvas); + + container_->Add(group); + group->LayoutBottomToSibling("UIKit_Draw_Line_Test_Line_003", 10); // 10: offset + group->LayoutRightToSibling("UIKit_Draw_Line_Test_Line_005", DELTA_X); +} + +void UITestDrawLine::UIKit_Draw_Line_Test_Line_007() +{ + if (container_ == nullptr) { + return; + } + + UIViewGroup* group = CreateTestCaseGroup(); + group->SetViewId("UIKit_Draw_Line_Test_Line_007"); + group->SetPosition(0, 0); + + UILabel* label = CreateTitleLabel(); + group->Add(label); + label->SetText("宽度为零直线绘制 "); + + UICanvas* canvas = CreateCanvas(); + Paint paint; + paint.SetStrokeWidth(0); // 0 : stroke width + canvas->DrawLine({10, 190}, {190, 10}, paint); // 10 : start x 190 : start y 190 : end x 10 : end y + group->Add(canvas); + + container_->Add(group); + group->LayoutBottomToSibling("UIKit_Draw_Line_Test_Line_004", 10); // 10 : offset size +} + +void UITestDrawLine::UIKit_Draw_Line_Test_Line_008() +{ + if (container_ == nullptr) { + return; + } + + UIViewGroup* group = CreateTestCaseGroup(); + group->SetViewId("UIKit_Draw_Line_Test_Line_008"); + group->SetPosition(0, 0); + + UILabel* label = CreateTitleLabel(); + group->Add(label); + label->SetText("不同宽度的直线绘制 "); + + UICanvas* canvas = CreateCanvas(); + Paint paint; + paint.SetStrokeWidth(2); // 2 : stroke width + canvas->DrawLine({10, 190}, {190, 10}, paint); // 10 : start x 190 : start y 190 : end x 10 : end y + Paint paint2; + paint2.SetStrokeWidth(4); // 4 : stroke width + canvas->DrawLine({30, 190}, {190, 30}, paint2); // 30 : start x 190 : start y 190 : end x 30 : end y + Paint paint3; + paint3.SetStrokeWidth(5); // 5 : stroke width + canvas->DrawLine({50, 190}, {190, 50}, paint3); // 50 : start x 190 : start y 190 : end x 50 : end y + Paint paint4; + paint4.SetStrokeWidth(90); // 90 : stroke width + canvas->DrawLine({40, 90}, {90, 40}, paint4); // 40 : start x 90 : start y 90 : end x 40 : end y + group->Add(canvas); + container_->Add(group); + group->LayoutBottomToSibling("UIKit_Draw_Line_Test_Line_005", 10); // 10: offset + group->LayoutRightToSibling("UIKit_Draw_Line_Test_Line_007", DELTA_X); +} + +void UITestDrawLine::UIKit_Draw_Line_Test_Line_009() +{ + if (container_ == nullptr) { + return; + } + + UIViewGroup* group = CreateTestCaseGroup(); + group->SetViewId("UIKit_Draw_Line_Test_Line_009"); + group->SetPosition(0, 0); + + UILabel* label = CreateTitleLabel(); + group->Add(label); + label->SetText("全透明的直线绘制 "); + + UICanvas* canvas = CreateCanvas(); + Paint paint; + paint.SetOpacity(OPA_TRANSPARENT); + canvas->DrawLine({10, 190}, {190, 10}, paint); // 10 : start x 190 : start y 190 : end x 10 : end y + group->Add(canvas); + container_->Add(group); + group->LayoutBottomToSibling("UIKit_Draw_Line_Test_Line_006", 10); // 10: offset + group->LayoutRightToSibling("UIKit_Draw_Line_Test_Line_008", DELTA_X); +} + +void UITestDrawLine::UIKit_Draw_Line_Test_Line_010() +{ + if (container_ == nullptr) { + return; + } + + UIViewGroup* group = CreateTestCaseGroup(); + group->SetViewId("UIKit_Draw_Line_Test_Line_010"); + group->SetPosition(0, 0); + + UILabel* label = CreateTitleLabel(); + group->Add(label); + label->SetText("不透明的直线绘制 "); + + UICanvas* canvas = CreateCanvas(); + Paint paint; + paint.SetOpacity(OPA_OPAQUE); + canvas->DrawLine({10, 190}, {190, 10}, paint); // 10 : start x 190 : start y 190 : end x 10 : end y + group->Add(canvas); + + container_->Add(group); + group->LayoutBottomToSibling("UIKit_Draw_Line_Test_Line_007", 10); // 10 : offset size +} + +void UITestDrawLine::UIKit_Draw_Line_Test_Line_011() +{ + if (container_ == nullptr) { + return; + } + + UIViewGroup* group = CreateTestCaseGroup(); + group->SetViewId("UIKit_Draw_Line_Test_Line_011"); + group->SetPosition(0, 0); + + UILabel* label = CreateTitleLabel(); + group->Add(label); + label->SetText("不同透明度的直线绘制 "); + + UICanvas* canvas = CreateCanvas(); + Paint paint; + paint.SetOpacity(51); // 51 : opacity size + canvas->DrawLine({10, 190}, {190, 10}, paint); // 10 : start x 190 : start y 190 : end x 10 : end y + Paint paint2; + paint2.SetOpacity(127); // 127 : opacity size + canvas->DrawLine({30, 190}, {190, 30}, paint2); // 30 : start x 190 : start y 190 : end x 30 : end y + Paint paint3; + paint3.SetOpacity(178); // 178 : opacity size + canvas->DrawLine({50, 190}, {190, 50}, paint3); // 50 : start x 190 : start y 190 : end x 50 : end y + group->Add(canvas); + container_->Add(group); + group->LayoutBottomToSibling("UIKit_Draw_Line_Test_Line_008", 10); // 10 : offset size + group->LayoutRightToSibling("UIKit_Draw_Line_Test_Line_010", DELTA_X); +} + +void UITestDrawLine::UIKit_Draw_Line_Test_Line_012() +{ + if (container_ == nullptr) { + return; + } + + UIViewGroup* group = CreateTestCaseGroup(); + group->SetViewId("UIKit_Draw_Line_Test_Line_012"); + group->SetPosition(0, 0); + + UILabel* label = CreateTitleLabel(); + group->Add(label); + label->SetText("不同颜色的直线绘制 "); + + UICanvas* canvas = CreateCanvas(); + Paint paint; + paint.SetStrokeColor(Color::Red()); + canvas->DrawLine({10, 190}, {190, 10}, paint); // 10 : start x 190 : start y 190 : end x 10 : end y + Paint paint2; + paint2.SetStrokeColor(Color::Yellow()); + canvas->DrawLine({30, 190}, {190, 30}, paint2); // 30 : start x 190 : start y 190 : end x 30 : end y + Paint paint3; + paint3.SetStrokeColor(Color::Green()); + canvas->DrawLine({50, 190}, {190, 50}, paint3); // 50 : start x 190 : start y 190 : end x 50 : end y + group->Add(canvas); + container_->Add(group); + group->LayoutBottomToSibling("UIKit_Draw_Line_Test_Line_009", 10); // 10 : offset size + group->LayoutRightToSibling("UIKit_Draw_Line_Test_Line_011", DELTA_X); +} +} // namespace OHOS \ No newline at end of file diff --git a/test/uitest/test_draw_line/ui_test_draw_line.h b/test/uitest/test_draw_line/ui_test_draw_line.h new file mode 100755 index 0000000..10560ca --- /dev/null +++ b/test/uitest/test_draw_line/ui_test_draw_line.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef UI_TEST_DRAW_LINE_H +#define UI_TEST_DRAW_LINE_H + +#include "components/ui_canvas.h" +#include "components/ui_label.h" +#include "components/ui_scroll_view.h" +#include "components/ui_view_group.h" +#include "ui_test.h" + +namespace OHOS { +class UITestDrawLine : public UITest { +public: + UITestDrawLine() {} + ~UITestDrawLine() {} + void SetUp() override; + void TearDown() override; + UIView* GetTestView() override; + + /** + * @brief Test draw line Function + */ + void UIKit_Draw_Line_Test_Line_001(); + void UIKit_Draw_Line_Test_Line_002(); + void UIKit_Draw_Line_Test_Line_003(); + void UIKit_Draw_Line_Test_Line_004(); + void UIKit_Draw_Line_Test_Line_005(); + void UIKit_Draw_Line_Test_Line_006(); + void UIKit_Draw_Line_Test_Line_007(); + void UIKit_Draw_Line_Test_Line_008(); + void UIKit_Draw_Line_Test_Line_009(); + void UIKit_Draw_Line_Test_Line_010(); + void UIKit_Draw_Line_Test_Line_011(); + void UIKit_Draw_Line_Test_Line_012(); + +private: + UIViewGroup* CreateTestCaseGroup() const; + UILabel* CreateTitleLabel() const; + UICanvas* CreateCanvas() const; + UIScrollView* container_ = nullptr; +}; +} // namespace OHOS +#endif // UI_TEST_DRAW_LINE_H diff --git a/test/uitest/test_draw_rect/ui_test_draw_rect.cpp b/test/uitest/test_draw_rect/ui_test_draw_rect.cpp new file mode 100755 index 0000000..7731717 --- /dev/null +++ b/test/uitest/test_draw_rect/ui_test_draw_rect.cpp @@ -0,0 +1,1427 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "ui_test_draw_rect.h" +#include "common/screen.h" +#include "components/ui_button.h" +#include "components/ui_label.h" +#include "components/ui_view_group.h" + +namespace OHOS { +void UITestDrawRect::SetUp() +{ + if (container_ == nullptr) { + container_ = new UIScrollView(); + container_->Resize(Screen::GetInstance().GetWidth(), Screen::GetInstance().GetHeight() - BACK_BUTTON_HEIGHT); + container_->SetHorizontalScrollState(false); + } +} + +void UITestDrawRect::TearDown() +{ + DeleteChildren(container_); + container_ = nullptr; +} + +UIView* UITestDrawRect::GetTestView() +{ + UIKit_DrawRect_Test_RectNoBorder_001(); + UIKit_DrawRect_Test_RectNoBorder_002(); + UIKit_DrawRect_Test_RectNoBorder_003(); + UIKit_DrawRect_Test_RectNoBorder_004(); + UIKit_DrawRect_Test_RectNoBorder_005(); + UIKit_DrawRect_Test_RectNoBorder_006(); + UIKit_DrawRect_Test_RectNoBorder_007(); + UIKit_DrawRect_Test_RectNoBorder_008(); + UIKit_DrawRect_Test_RectNoBorder_009(); + UIKit_DrawRect_Test_RectNoBorder_0010(); + UIKit_DrawRect_Test_RectBorderNoRadius_001(); + UIKit_DrawRect_Test_RectBorderNoRadius_002(); + UIKit_DrawRect_Test_RectBorderRadius_001(); + UIKit_DrawRect_Test_RectBorderRadius_002(); + UIKit_DrawRect_Test_RectBorderRadius_003(); + UIKit_DrawRect_Test_RectBorderRadius_004(); + UIKit_DrawRect_Test_RectBorderRadius_005(); + UIKit_DrawRect_Test_RectBorderRadius_006(); + UIKit_DrawRect_Test_RectBorderRadius_007(); + UIKit_DrawRect_Test_RectBorderRadius_008(); + UIKit_DrawRect_Test_RectBorderRadius_009(); + UIKit_DrawRect_Test_RectBorderRadius_010(); + UIKit_DrawRect_Test_RectBorderRadius_011(); + + UIKit_DrawRect_Test_Rect_001(); + UIKit_DrawRect_Test_RectColor_001(); + UIKit_DrawRect_Test_RectRadius_001(); + UIKit_DrawRect_Test_RectRadius_002(); + UIKit_DrawRect_Test_RectRadius_003(); + UIKit_DrawRect_Test_RectRadius_004(); + UIKit_DrawRect_Test_RectOpacity_001(); + UIKit_DrawRect_Test_RectOpacity_002(); + UIKit_DrawRect_Test_RectOpacity_003(); + UIKit_DrawRect_Test_RectBorderColor_001(); + UIKit_DrawRect_Test_RectBorderWidth_001(); + UIKit_DrawRect_Test_RectBorderWidth_002(); + UIKit_DrawRect_Test_RectBorderOpacity_001(); + UIKit_DrawRect_Test_RectBorderOpacity_002(); + UIKit_DrawRect_Test_RectBorderOpacity_003(); + UIKit_DrawRect_Test_RectPadding_001(); + UIKit_DrawRect_Test_RectPadding_002(); + UIKit_DrawRect_Test_RectMargin_001(); + UIKit_DrawRect_Test_RectMargin_002(); + UIKit_DrawRect_Test_RectPaddingMargin_001(); + UIKit_DrawRect_Test_RectPaddingMargin_002(); + UIKit_DrawRect_Test_RectWidthAndHeight_001(); + UIKit_DrawRect_Test_RectWidthAndHeight_002(); + UIKit_DrawRect_Test_RectWidthAndHeight_003(); + return container_; +} + +UIViewGroup* UITestDrawRect::CreateTestCaseGroup() const +{ + UIViewGroup* group = new UIViewGroup(); + group->Resize(Screen::GetInstance().GetWidth(), 180); // 180 : value + return group; +} + +UILabel* UITestDrawRect::CreateTitleLabel() const +{ + UILabel* label = new UILabel(); + label->SetPosition(TEXT_DISTANCE_TO_LEFT_SIDE, TEXT_DISTANCE_TO_TOP_SIDE, + Screen::GetInstance().GetWidth() - VIEW_DISTANCE_TO_LEFT_SIDE, TITLE_LABEL_DEFAULT_HEIGHT); + label->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); + return label; +} + +UIView* UITestDrawRect::CreateUIView() const +{ + UIView* view = new UIView(); + view->SetStyle(STYLE_BACKGROUND_COLOR, Color::Green().full); + view->SetStyle(STYLE_BACKGROUND_OPA, 127); // 127 : background opacity + view->SetStyle(STYLE_BORDER_RADIUS, 5); // 5 : radius value + view->SetStyle(STYLE_BORDER_COLOR, Color::Gray().full); + view->SetStyle(STYLE_BORDER_OPA, 127); // 127 : border opacity + view->SetStyle(STYLE_BORDER_WIDTH, 20); // 20 : border width + view->SetStyle(STYLE_PADDING_LEFT, 0); + view->SetStyle(STYLE_PADDING_RIGHT, 0); + view->SetStyle(STYLE_PADDING_TOP, 0); + view->SetStyle(STYLE_PADDING_BOTTOM, 0); + view->SetStyle(STYLE_MARGIN_LEFT, 0); + view->SetStyle(STYLE_MARGIN_RIGHT, 0); + view->SetStyle(STYLE_MARGIN_TOP, 0); + view->SetStyle(STYLE_MARGIN_BOTTOM, 0); + return view; +} + +void UITestDrawRect::UIKit_DrawRect_Test_RectNoBorder_001() +{ + if (container_ == nullptr) { + return; + } + + UIViewGroup* group = CreateTestCaseGroup(); + group->SetViewId("UIKit_DrawRect_Test_RectNoBorder_001"); + group->SetPosition(0, 0); + + UILabel* label = CreateTitleLabel(); + label->SetText("矩形无border, radius=0"); + group->Add(label); + + UIView* view = CreateUIView(); + int16_t width = 120; // 120 : width + int16_t height = 50; // 50 : height + view->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE, VIEW_DISTANCE_TO_TOP_SIDE); + view->SetStyle(STYLE_BORDER_WIDTH, 0); + view->SetStyle(STYLE_BORDER_RADIUS, 0); + view->Resize(width, height); + group->Add(view); + + container_->Add(group); +} + +void UITestDrawRect::UIKit_DrawRect_Test_RectNoBorder_002() +{ + if (container_ == nullptr) { + return; + } + + UIViewGroup* group = CreateTestCaseGroup(); + group->SetViewId("UIKit_DrawRect_Test_RectNoBorder_002"); + group->SetPosition(0, 0); + + UILabel* label = CreateTitleLabel(); + label->SetText("矩形无border, radius>0, width > height, radius > height/2"); + group->Add(label); + + UIView* view = CreateUIView(); + int16_t width = 120; // 120 : width + int16_t height = 50; // 50 : height + view->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE, VIEW_DISTANCE_TO_TOP_SIDE); + view->SetStyle(STYLE_BORDER_WIDTH, 0); + view->SetStyle(STYLE_BORDER_RADIUS, height / 2 + 10); // 2 : half height 10 : offset + view->Resize(width, height); + group->Add(view); + + container_->Add(group); + group->LayoutBottomToSibling("UIKit_DrawRect_Test_RectNoBorder_001", 10); // 10 : offset size +} + +void UITestDrawRect::UIKit_DrawRect_Test_RectNoBorder_003() +{ + if (container_ == nullptr) { + return; + } + + UIViewGroup* group = CreateTestCaseGroup(); + group->SetViewId("UIKit_DrawRect_Test_RectNoBorder_003"); + group->SetPosition(0, 0); + + UILabel* label = CreateTitleLabel(); + label->SetText("矩形无border, radius>0, width > height, radius = height/2 "); + group->Add(label); + + UIView* view = CreateUIView(); + int16_t width = 120; // 120 : width size + int16_t height = 50; // 50 : height size + view->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE, VIEW_DISTANCE_TO_TOP_SIDE); + view->SetStyle(STYLE_BORDER_WIDTH, 0); + view->SetStyle(STYLE_BORDER_RADIUS, height / 2); // 2 : half height + view->Resize(width, height); + group->Add(view); + + container_->Add(group); + group->LayoutBottomToSibling("UIKit_DrawRect_Test_RectNoBorder_002", 10); // 10 : offset size +} + +void UITestDrawRect::UIKit_DrawRect_Test_RectNoBorder_004() +{ + if (container_ == nullptr) { + return; + } + + UIViewGroup* group = CreateTestCaseGroup(); + group->SetViewId("UIKit_DrawRect_Test_RectNoBorder_004"); + group->SetPosition(0, 0); + + UILabel* label = CreateTitleLabel(); + label->SetText("矩形无border, radius>0, width > height, radius < height/2 "); + group->Add(label); + + UIView* view = CreateUIView(); + int16_t width = 120; // 120 : width size + int16_t height = 50; // 50 : height size + view->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE, VIEW_DISTANCE_TO_TOP_SIDE); + view->SetStyle(STYLE_BORDER_WIDTH, 0); + view->SetStyle(STYLE_BORDER_RADIUS, height / 2 - 10); // 2 : half height 10 : offset + view->Resize(width, height); + group->Add(view); + + container_->Add(group); + group->LayoutBottomToSibling("UIKit_DrawRect_Test_RectNoBorder_003", 10); // 10 : offset size +} + +void UITestDrawRect::UIKit_DrawRect_Test_RectNoBorder_005() +{ + if (container_ == nullptr) { + return; + } + + UIViewGroup* group = CreateTestCaseGroup(); + group->SetViewId("UIKit_DrawRect_Test_RectNoBorder_005"); + group->SetPosition(0, 0); + + UILabel* label = CreateTitleLabel(); + label->SetText("矩形无border, radius>0, width = height, radius > height/2 "); + group->Add(label); + + UIView* view = CreateUIView(); + int16_t width = 50; // 50 : width + int16_t height = width; + view->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE, VIEW_DISTANCE_TO_TOP_SIDE); + view->SetStyle(STYLE_BORDER_WIDTH, 0); + view->SetStyle(STYLE_BORDER_RADIUS, height / 2 + 10); // 2 : half height 10 : offset + view->Resize(width, height); + group->Add(view); + + container_->Add(group); + group->LayoutBottomToSibling("UIKit_DrawRect_Test_RectNoBorder_004", 10); // 10 : offset size +} + +void UITestDrawRect::UIKit_DrawRect_Test_RectNoBorder_006() +{ + if (container_ == nullptr) { + return; + } + + UIViewGroup* group = CreateTestCaseGroup(); + group->SetViewId("UIKit_DrawRect_Test_RectNoBorder_006"); + group->SetPosition(0, 0); + + UILabel* label = CreateTitleLabel(); + label->SetText("矩形无border, radius>0, width = height, radius = height/2 "); + group->Add(label); + + UIView* view = CreateUIView(); + int16_t width = 50; // 50 : width + int16_t height = width; + view->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE, VIEW_DISTANCE_TO_TOP_SIDE); + view->SetStyle(STYLE_BORDER_WIDTH, 0); + view->SetStyle(STYLE_BORDER_RADIUS, height / 2); // 2 : half + view->Resize(width, height); + group->Add(view); + + container_->Add(group); + group->LayoutBottomToSibling("UIKit_DrawRect_Test_RectNoBorder_005", 10); // 10 : offset size +} + +void UITestDrawRect::UIKit_DrawRect_Test_RectNoBorder_007() +{ + if (container_ == nullptr) { + return; + } + + UIViewGroup* group = CreateTestCaseGroup(); + group->SetViewId("UIKit_DrawRect_Test_RectNoBorder_007"); + group->SetPosition(0, 0); + + UILabel* label = CreateTitleLabel(); + label->SetText("矩形无border, radius>0, width = height, radius < height/2 "); + group->Add(label); + + UIView* view = CreateUIView(); + int16_t width = 50; // 50 : width + int16_t height = width; + view->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE, VIEW_DISTANCE_TO_TOP_SIDE); + view->SetStyle(STYLE_BORDER_WIDTH, 0); + view->SetStyle(STYLE_BORDER_RADIUS, height / 2 - 10); // 2 : half height 10 : offset + view->Resize(width, height); + group->Add(view); + + container_->Add(group); + group->LayoutBottomToSibling("UIKit_DrawRect_Test_RectNoBorder_006", 10); // 10 : offset size +} + +void UITestDrawRect::UIKit_DrawRect_Test_RectNoBorder_008() +{ + if (container_ == nullptr) { + return; + } + + UIViewGroup* group = CreateTestCaseGroup(); + group->SetViewId("UIKit_DrawRect_Test_RectNoBorder_008"); + group->SetPosition(0, 0); + + UILabel* label = CreateTitleLabel(); + label->SetText("矩形无border, radius>0, width < height, radius > width/2 "); + group->Add(label); + + UIView* view = CreateUIView(); + int16_t width = 50; // 50 : width + int16_t height = 120; // 120 : height + view->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE, VIEW_DISTANCE_TO_TOP_SIDE); + view->SetStyle(STYLE_BORDER_WIDTH, 0); + view->SetStyle(STYLE_BORDER_RADIUS, width / 2 + 10); // 2 : half width 10 : offset + view->Resize(width, height); + group->Add(view); + + container_->Add(group); + group->LayoutBottomToSibling("UIKit_DrawRect_Test_RectNoBorder_007", 10); // 10 : offset size +} + +void UITestDrawRect::UIKit_DrawRect_Test_RectNoBorder_009() +{ + if (container_ == nullptr) { + return; + } + + UIViewGroup* group = CreateTestCaseGroup(); + group->SetViewId("UIKit_DrawRect_Test_RectNoBorder_009"); + group->SetPosition(0, 0); + + UILabel* label = CreateTitleLabel(); + label->SetText("矩形无border, radius>0, width < height, radius = width/2 "); + group->Add(label); + + UIView* view = CreateUIView(); + int16_t width = 51; // 51 : width + int16_t height = 120; // 120 : height + view->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE, VIEW_DISTANCE_TO_TOP_SIDE); + view->SetStyle(STYLE_BORDER_WIDTH, 0); + view->SetStyle(STYLE_BORDER_RADIUS, width / 2); // 2 : half width + view->Resize(width, height); + group->Add(view); + + container_->Add(group); + group->LayoutBottomToSibling("UIKit_DrawRect_Test_RectNoBorder_008", 10); // 10 : offset size +} + +void UITestDrawRect::UIKit_DrawRect_Test_RectNoBorder_0010() +{ + if (container_ == nullptr) { + return; + } + + UIViewGroup* group = CreateTestCaseGroup(); + group->SetViewId("UIKit_DrawRect_Test_RectNoBorder_0010"); + group->SetPosition(0, 0); + + UILabel* label = CreateTitleLabel(); + label->SetText("矩形无border, radius>0, width < height, radius < width/2 "); + group->Add(label); + + UIView* view = CreateUIView(); + int16_t width = 50; // 50 : width + int16_t height = 120; // 120 : height + view->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE, VIEW_DISTANCE_TO_TOP_SIDE); + view->SetStyle(STYLE_BORDER_WIDTH, 0); + view->SetStyle(STYLE_BORDER_RADIUS, width / 2 - 10); // 2 : half width 10 : offset + view->Resize(width, height); + group->Add(view); + + container_->Add(group); + group->LayoutBottomToSibling("UIKit_DrawRect_Test_RectNoBorder_009", 10); // 10 : offset size +} + +void UITestDrawRect::UIKit_DrawRect_Test_RectBorderNoRadius_001() +{ + if (container_ == nullptr) { + return; + } + + UIViewGroup* group = CreateTestCaseGroup(); + group->SetViewId("UIKit_DrawRect_Test_RectBorderNoRadius_001"); + group->SetPosition(0, 0); + + UILabel* label = CreateTitleLabel(); + label->SetText("矩形有border, radius=0"); + group->Add(label); + + UIView* view = CreateUIView(); + int16_t width = 120; // 120 : width + int16_t height = 50; // 50 : height + view->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE, VIEW_DISTANCE_TO_TOP_SIDE); + view->SetStyle(STYLE_BORDER_WIDTH, 10); // 10 : value + view->SetStyle(STYLE_BORDER_RADIUS, 0); + view->Resize(width, height); + group->Add(view); + + container_->Add(group); + group->LayoutBottomToSibling("UIKit_DrawRect_Test_RectNoBorder_0010", 10); // 10 : offset size +} + +void UITestDrawRect::UIKit_DrawRect_Test_RectBorderNoRadius_002() +{ + if (container_ == nullptr) { + return; + } + + UIViewGroup* group = CreateTestCaseGroup(); + group->SetViewId("UIKit_DrawRect_Test_RectBorderNoRadius_002"); + group->SetPosition(0, 0); + + UILabel* label = CreateTitleLabel(); + label->SetText("矩形有border = 1, radius=0"); + group->Add(label); + + UIView* view = CreateUIView(); + int16_t width = 120; // 120 : width + int16_t height = 50; // 50 : height + view->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE, VIEW_DISTANCE_TO_TOP_SIDE); + view->SetStyle(STYLE_BORDER_WIDTH, 1); // 1 : value + view->SetStyle(STYLE_BORDER_RADIUS, 0); + view->Resize(width, height); + group->Add(view); + + container_->Add(group); + group->LayoutBottomToSibling("UIKit_DrawRect_Test_RectBorderNoRadius_001", 10); // 10 : offset size +} + +void UITestDrawRect::UIKit_DrawRect_Test_RectBorderRadius_001() +{ + if (container_ == nullptr) { + return; + } + + UIViewGroup* group = CreateTestCaseGroup(); + group->SetViewId("UIKit_DrawRect_Test_RectBorderRadius_001"); + group->SetPosition(0, 0); + + UILabel* label = CreateTitleLabel(); + label->SetText("矩形有border, radiusAdd(label); + + UIView* view = CreateUIView(); + int16_t width = 120; // 120 : width + int16_t height = 50; // 50 : height + int16_t borderWidth = 10; // 10 : borderWidth + view->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE, VIEW_DISTANCE_TO_TOP_SIDE); + view->SetStyle(STYLE_BORDER_WIDTH, borderWidth); + view->SetStyle(STYLE_BORDER_RADIUS, borderWidth - 5); // 5 : math_num + view->Resize(width, height); + group->Add(view); + + container_->Add(group); + group->LayoutBottomToSibling("UIKit_DrawRect_Test_RectBorderNoRadius_001", 10); // 10 : offset size +} + +void UITestDrawRect::UIKit_DrawRect_Test_RectBorderRadius_002() +{ + if (container_ == nullptr) { + return; + } + + UIViewGroup* group = CreateTestCaseGroup(); + group->SetViewId("UIKit_DrawRect_Test_RectBorderRadius_002"); + group->SetPosition(0, 0); + + UILabel* label = CreateTitleLabel(); + label->SetText("border场景,radius>border.width,宽度 >高度,radius > 高度/2 + border.width"); + group->Add(label); + + UIView* view = CreateUIView(); + int16_t width = 120; // 120 : width + int16_t height = 50; // 50 : height + int16_t borderWidth = 10; // 10 : borderWidth + view->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE, VIEW_DISTANCE_TO_TOP_SIDE); + view->SetStyle(STYLE_BORDER_WIDTH, borderWidth); + view->SetStyle(STYLE_BORDER_RADIUS, height / 2 + borderWidth + 5); // 2 : half height 5 : offset + view->Resize(width, height); + group->Add(view); + + container_->Add(group); + group->LayoutBottomToSibling("UIKit_DrawRect_Test_RectBorderRadius_001", 10); // 10 : offset size +} + +void UITestDrawRect::UIKit_DrawRect_Test_RectBorderRadius_003() +{ + if (container_ == nullptr) { + return; + } + + UIViewGroup* group = CreateTestCaseGroup(); + group->SetViewId("UIKit_DrawRect_Test_RectBorderRadius_003"); + group->SetPosition(0, 0); + + UILabel* label = CreateTitleLabel(); + label->SetText("border场景,radius>border.width,宽度>高度,radius = 高度/2 + border.width"); + group->Add(label); + + UIView* view = CreateUIView(); + int16_t width = 120; // 120 : width + int16_t height = 50; // 50 : height + int16_t borderWidth = 10; // 10 : borderWidth + view->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE, VIEW_DISTANCE_TO_TOP_SIDE); + view->SetStyle(STYLE_BORDER_WIDTH, borderWidth); + view->SetStyle(STYLE_BORDER_RADIUS, height / 2 + borderWidth); // 2 : half height + view->Resize(width, height); + group->Add(view); + + container_->Add(group); + group->LayoutBottomToSibling("UIKit_DrawRect_Test_RectBorderRadius_002", 10); // 10 : offset size +} + +void UITestDrawRect::UIKit_DrawRect_Test_RectBorderRadius_004() +{ + if (container_ == nullptr) { + return; + } + + UIViewGroup* group = CreateTestCaseGroup(); + group->SetViewId("UIKit_DrawRect_Test_RectBorderRadius_004"); + group->SetPosition(0, 0); + + UILabel* label = CreateTitleLabel(); + label->SetText("border场景,radius>border.width,宽度>高度,radius < 高度/2 + border.width"); + group->Add(label); + + UIView* view = CreateUIView(); + int16_t width = 120; // 120 : width + int16_t height = 50; // 50 : height + int16_t borderWidth = 10; // 10 : borderWidth + view->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE, VIEW_DISTANCE_TO_TOP_SIDE); + view->SetStyle(STYLE_BORDER_WIDTH, borderWidth); + view->SetStyle(STYLE_BORDER_RADIUS, height / 2 + borderWidth - 5); // 2 : half height 5 : offset + view->Resize(width, height); + group->Add(view); + + container_->Add(group); + group->LayoutBottomToSibling("UIKit_DrawRect_Test_RectBorderRadius_003", 10); // 10 : offset size +} + +void UITestDrawRect::UIKit_DrawRect_Test_RectBorderRadius_005() +{ + if (container_ == nullptr) { + return; + } + + UIViewGroup* group = CreateTestCaseGroup(); + group->SetViewId("UIKit_DrawRect_Test_RectBorderRadius_005"); + group->SetPosition(0, 0); + + UILabel* label = CreateTitleLabel(); + label->SetText("border场景,radius>border.width,宽度=高度,radius > 宽度/2 + border.width"); + group->Add(label); + + UIView* view = CreateUIView(); + int16_t width = 50; // 50 : width + int16_t height = 50; // 50 : height + int16_t borderWidth = 10; // 10 : borderWidth + view->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE, VIEW_DISTANCE_TO_TOP_SIDE); + view->SetStyle(STYLE_BORDER_WIDTH, borderWidth); + view->SetStyle(STYLE_BORDER_RADIUS, width / 2 + borderWidth + 5); // 2 : half width 5 : offset + view->Resize(width, height); + group->Add(view); + + container_->Add(group); + group->LayoutBottomToSibling("UIKit_DrawRect_Test_RectBorderRadius_004", 10); // 10 : offset size +} + +void UITestDrawRect::UIKit_DrawRect_Test_RectBorderRadius_006() +{ + if (container_ == nullptr) { + return; + } + + UIViewGroup* group = CreateTestCaseGroup(); + group->SetViewId("UIKit_DrawRect_Test_RectBorderRadius_006"); + group->SetPosition(0, 0); + + UILabel* label = CreateTitleLabel(); + label->SetText("border场景,radius>border.width,宽度=高度,radius = 宽度/2 + border.width"); + group->Add(label); + + UIView* view = CreateUIView(); + int16_t width = 50; // 50 : width + int16_t height = 50; // 50 : height + int16_t borderWidth = 10; // 10 : borderWidth + view->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE, VIEW_DISTANCE_TO_TOP_SIDE); + view->SetStyle(STYLE_BORDER_WIDTH, borderWidth); + view->SetStyle(STYLE_BORDER_RADIUS, width / 2 + borderWidth); // 2 : half width + view->Resize(width, height); + group->Add(view); + + container_->Add(group); + group->LayoutBottomToSibling("UIKit_DrawRect_Test_RectBorderRadius_005", 10); // 10 : offset size +} + +void UITestDrawRect::UIKit_DrawRect_Test_RectBorderRadius_007() +{ + if (container_ == nullptr) { + return; + } + + UIViewGroup* group = CreateTestCaseGroup(); + group->SetViewId("UIKit_DrawRect_Test_RectBorderRadius_007"); + group->SetPosition(0, 0); + + UILabel* label = CreateTitleLabel(); + label->SetText("border场景,radius>border.width,宽度=高度,radius < 宽度/2 + border.width"); + group->Add(label); + + UIView* view = CreateUIView(); + int16_t width = 50; // 50 : width + int16_t height = 50; // 50 : height + int16_t borderWidth = 10; // 10 : borderWidth + view->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE, VIEW_DISTANCE_TO_TOP_SIDE); + view->SetStyle(STYLE_BORDER_WIDTH, borderWidth); + view->SetStyle(STYLE_BORDER_RADIUS, width / 2 + borderWidth - 5); // 2 : half width 5 : offset + view->Resize(width, height); + group->Add(view); + + container_->Add(group); + group->LayoutBottomToSibling("UIKit_DrawRect_Test_RectBorderRadius_006", 10); // 10 : offset size +} + +void UITestDrawRect::UIKit_DrawRect_Test_RectBorderRadius_008() +{ + if (container_ == nullptr) { + return; + } + + UIViewGroup* group = CreateTestCaseGroup(); + group->SetViewId("UIKit_DrawRect_Test_RectBorderRadius_008"); + group->SetPosition(0, 0); + + UILabel* label = CreateTitleLabel(); + label->SetText("border场景,radius>border.width,宽度<高度,radius > 宽度/2 + border.width"); + group->Add(label); + + UIView* view = CreateUIView(); + int16_t width = 50; // 50 : width + int16_t height = 100; // 100 : height + int16_t borderWidth = 10; // 10 : borderWidth + view->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE, VIEW_DISTANCE_TO_TOP_SIDE); + view->SetStyle(STYLE_BORDER_WIDTH, borderWidth); + view->SetStyle(STYLE_BORDER_RADIUS, width / 2 + borderWidth + 5); // 2 : half width 5 : math_num + view->Resize(width, height); + group->Add(view); + + container_->Add(group); + group->LayoutBottomToSibling("UIKit_DrawRect_Test_RectBorderRadius_007", 10); // 10 : value +} + +void UITestDrawRect::UIKit_DrawRect_Test_RectBorderRadius_009() +{ + if (container_ == nullptr) { + return; + } + + UIViewGroup* group = CreateTestCaseGroup(); + group->SetViewId("UIKit_DrawRect_Test_RectBorderRadius_009"); + group->SetPosition(0, 0); + + UILabel* label = CreateTitleLabel(); + label->SetText("border场景,radius>border.width,宽度<高度,radius = 宽度/2 + border.width"); + group->Add(label); + + UIView* view = CreateUIView(); + int16_t width = 50; // 50 : width + int16_t height = 100; // 100 : height + int16_t borderWidth = 10; // 10 : value + view->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE, VIEW_DISTANCE_TO_TOP_SIDE); + view->SetStyle(STYLE_BORDER_WIDTH, borderWidth); + view->SetStyle(STYLE_BORDER_RADIUS, width / 2 + borderWidth); // 2 : math_num + view->Resize(width, height); + group->Add(view); + + container_->Add(group); + group->LayoutBottomToSibling("UIKit_DrawRect_Test_RectBorderRadius_008", 10); // 10 : value +} + +void UITestDrawRect::UIKit_DrawRect_Test_RectBorderRadius_010() +{ + if (container_ == nullptr) { + return; + } + + UIViewGroup* group = CreateTestCaseGroup(); + group->SetViewId("UIKit_DrawRect_Test_RectBorderRadius_010"); + group->SetPosition(0, 0); + + UILabel* label = CreateTitleLabel(); + label->SetText("border场景,radius>border.width,宽度<高度,radius < 宽度/2 + border.width"); + group->Add(label); + + UIView* view = CreateUIView(); + int16_t width = 50; // 50 : width + int16_t height = 100; // 100 : height + int16_t borderWidth = 10; // 10 : borderWidth + view->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE, VIEW_DISTANCE_TO_TOP_SIDE); + view->SetStyle(STYLE_BORDER_WIDTH, borderWidth); + view->SetStyle(STYLE_BORDER_RADIUS, width / 2 + borderWidth - 5); // 2 : math_num 5 : math_num + view->Resize(width, height); + group->Add(view); + + container_->Add(group); + group->LayoutBottomToSibling("UIKit_DrawRect_Test_RectBorderRadius_009", 10); // 10 : value +} + +void UITestDrawRect::UIKit_DrawRect_Test_RectBorderRadius_011() +{ + if (container_ == nullptr) { + return; + } + + UIViewGroup* group = CreateTestCaseGroup(); + group->SetViewId("UIKit_DrawRect_Test_RectBorderRadius_011"); + group->SetPosition(0, 0); + + UILabel* label = CreateTitleLabel(); + label->SetText("矩形有border = 2, radius = 1"); + group->Add(label); + + UIView* view = CreateUIView(); + int16_t width = 120; // 120 : width + int16_t height = 50; // 50 : height + int16_t borderWidth = 10; // 10 : borderWidth + view->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE, VIEW_DISTANCE_TO_TOP_SIDE); + view->SetStyle(STYLE_BORDER_WIDTH, 2); // 2: borderWidth + view->SetStyle(STYLE_BORDER_RADIUS, 1); // 1 : math_num + view->Resize(width, height); + group->Add(view); + + container_->Add(group); + group->LayoutBottomToSibling("UIKit_DrawRect_Test_RectBorderRadius_010", 10); // 10 : offset size +} + +void UITestDrawRect::UIKit_DrawRect_Test_Rect_001() +{ + if (container_ == nullptr) { + return; + } + + UIViewGroup* group = CreateTestCaseGroup(); + group->SetViewId("UIKit_DrawRect_Test_Rect_001"); + group->SetPosition(0, 0); + + UILabel* label = CreateTitleLabel(); + label->SetText("矩形绘制: "); + group->Add(label); + + UIView* view = CreateUIView(); + view->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE, VIEW_DISTANCE_TO_TOP_SIDE); + view->SetStyle(STYLE_BORDER_WIDTH, 15); // 15 : value + view->SetStyle(STYLE_BORDER_OPA, OPA_OPAQUE); + view->SetStyle(STYLE_BORDER_RADIUS, 10); // 10 : offset size + view->Resize(120, 50); // 120 : width 50 : weight + group->Add(view); + + container_->Add(group); + group->LayoutBottomToSibling("UIKit_DrawRect_Test_RectBorderRadius_009", 10); // 10 : offset size +} + +void UITestDrawRect::UIKit_DrawRect_Test_RectColor_001() +{ + if (container_ == nullptr) { + return; + } + + UIViewGroup* group = CreateTestCaseGroup(); + group->SetViewId("UIKit_DrawRect_Test_RectColor_001"); + + UILabel* label = CreateTitleLabel(); + label->SetText("设置不同颜色的矩形绘制 "); + group->Add(label); + + UIView* view = CreateUIView(); + view->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE, VIEW_DISTANCE_TO_TOP_SIDE); + view->SetStyle(STYLE_BORDER_WIDTH, 20); // 20 : value + view->SetStyle(STYLE_BORDER_RADIUS, 30); // 30 : value + view->Resize(120, 50); // 120 : width 50 : height + group->Add(view); + + UIView* view1 = CreateUIView(); + view1->SetPosition(250, 50); // 250 : start x 50 : start y + view1->SetStyle(STYLE_BORDER_WIDTH, 3); // 3 : value + view1->SetStyle(STYLE_BORDER_RADIUS, 3); // 3 : value + view1->Resize(120, 50); // 120 : width 50 : height + group->Add(view1); + + container_->Add(group); + group->LayoutBottomToSibling("UIKit_DrawRect_Test_Rect_001", 10); // 10 : offset size +} + +void UITestDrawRect::UIKit_DrawRect_Test_RectRadius_001() +{ + if (container_ == nullptr) { + return; + } + + UIViewGroup* group = CreateTestCaseGroup(); + group->SetViewId("UIKit_DrawRect_Test_RectRadius_001"); + + UILabel* label = CreateTitleLabel(); + label->SetText("设置圆角为零的矩形绘制 "); + group->Add(label); + + UIView* view = CreateUIView(); + view->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE, VIEW_DISTANCE_TO_TOP_SIDE); + view->SetStyle(STYLE_BORDER_WIDTH, 20); // 20 : value + view->SetStyle(STYLE_BORDER_RADIUS, 10); // 10 : value + view->Resize(120, 50); // 120 : width 50 : height + group->Add(view); + + container_->Add(group); + group->LayoutBottomToSibling("UIKit_DrawRect_Test_RectColor_001", 10); // 10 : offset size +} + +void UITestDrawRect::UIKit_DrawRect_Test_RectRadius_002() +{ + if (container_ == nullptr) { + return; + } + + UIViewGroup* group = CreateTestCaseGroup(); + group->SetViewId("UIKit_DrawRect_Test_RectRadius_002"); + + UILabel* label = CreateTitleLabel(); + label->SetText("设置圆角等于宽度的矩形绘制 "); + group->Add(label); + + UIView* view = CreateUIView(); + view->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE, VIEW_DISTANCE_TO_TOP_SIDE); + view->SetStyle(STYLE_BORDER_WIDTH, 20); // 20 : value + view->SetStyle(STYLE_BORDER_RADIUS, 50); // 50 : value + view->Resize(120, 50); // 120 : width 50 : height + group->Add(view); + + container_->Add(group); + group->LayoutBottomToSibling("UIKit_DrawRect_Test_RectRadius_001", 10); // 10 : offset size +} + +void UITestDrawRect::UIKit_DrawRect_Test_RectRadius_003() +{ + if (container_ == nullptr) { + return; + } + + UIViewGroup* group = CreateTestCaseGroup(); + group->SetViewId("UIKit_DrawRect_Test_RectRadius_003"); + + UILabel* label = CreateTitleLabel(); + label->SetText("设置圆角等于宽度的正方形绘制:"); + group->Add(label); + + UIView* view = CreateUIView(); + view->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE, VIEW_DISTANCE_TO_TOP_SIDE); + view->SetStyle(STYLE_BORDER_WIDTH, 20); // 20 : value + view->SetStyle(STYLE_BORDER_RADIUS, 50); // 50 : value + view->Resize(50, 50); // 50 : value 50 : value + group->Add(view); + + container_->Add(group); + group->LayoutBottomToSibling("UIKit_DrawRect_Test_RectRadius_002", 10); // 10 : offset size +} + +void UITestDrawRect::UIKit_DrawRect_Test_RectRadius_004() +{ + if (container_ == nullptr) { + return; + } + + UIViewGroup* group = CreateTestCaseGroup(); + group->SetViewId("UIKit_DrawRect_Test_RectRadius_004"); + + UILabel* label = CreateTitleLabel(); + label->SetText("设置不同圆角大小的矩形绘制 "); + group->Add(label); + + UIView* view = CreateUIView(); + view->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE, VIEW_DISTANCE_TO_TOP_SIDE); + view->SetStyle(STYLE_BORDER_WIDTH, 20); // 20 : value + view->SetStyle(STYLE_BORDER_RADIUS, 10); // 10 : value + view->Resize(120, 50); // 120 : width 50 : height + group->Add(view); + + UIView* view1 = CreateUIView(); + view1->SetPosition(250, 50); // 250 : offset 50 : offset + view1->SetStyle(STYLE_BORDER_WIDTH, 3); // 3 : value + view1->SetStyle(STYLE_BORDER_RADIUS, 5); // 5 : value + view1->Resize(120, 50); // 120 : width 50 : height + group->Add(view1); + + container_->Add(group); + group->LayoutBottomToSibling("UIKit_DrawRect_Test_RectRadius_003", 10); // 10 : offset size +} + +void UITestDrawRect::UIKit_DrawRect_Test_RectOpacity_001() +{ + if (container_ == nullptr) { + return; + } + + UIViewGroup* group = CreateTestCaseGroup(); + group->SetViewId("UIKit_DrawRect_Test_RectOpacity_001"); + + UILabel* label = CreateTitleLabel(); + label->SetText("设置不透明背景矩形绘制: "); + group->Add(label); + + UIView* view = CreateUIView(); + view->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE, VIEW_DISTANCE_TO_TOP_SIDE); + view->SetStyle(STYLE_BACKGROUND_OPA, OPA_OPAQUE); + view->Resize(120, 50); // 120 : width 50 : height + group->Add(view); + + container_->Add(group); + group->LayoutBottomToSibling("UIKit_DrawRect_Test_RectRadius_004", 10); // 10 : offset size +} + +void UITestDrawRect::UIKit_DrawRect_Test_RectOpacity_002() +{ + if (container_ == nullptr) { + return; + } + + UIViewGroup* group = CreateTestCaseGroup(); + group->SetViewId("UIKit_DrawRect_Test_RectOpacity_002"); + + UILabel* label = CreateTitleLabel(); + label->SetText("设置全透明背景矩形绘制:"); + group->Add(label); + + UIView* view = CreateUIView(); + view->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE, VIEW_DISTANCE_TO_TOP_SIDE); + view->SetStyle(STYLE_BACKGROUND_OPA, OPA_TRANSPARENT); + view->Resize(120, 50); // 120 : width 50 : height + group->Add(view); + + container_->Add(group); + group->LayoutBottomToSibling("UIKit_DrawRect_Test_RectOpacity_001", 10); // 10 : offset size +} + +void UITestDrawRect::UIKit_DrawRect_Test_RectOpacity_003() +{ + if (container_ == nullptr) { + return; + } + + UIViewGroup* group = CreateTestCaseGroup(); + group->SetViewId("UIKit_DrawRect_Test_RectOpacity_003"); + + UILabel* label = CreateTitleLabel(); + label->SetText("设置不同透明度矩形绘制 "); + group->Add(label); + + UIView* view = CreateUIView(); + view->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE, VIEW_DISTANCE_TO_TOP_SIDE); + view->SetStyle(STYLE_BACKGROUND_OPA, 102); // 102 : value + view->Resize(120, 50); // 120 : width 50 : height + group->Add(view); + + UIView* view1 = CreateUIView(); + view1->SetPosition(250, 50); // 250 : start x 50 : start y + view1->SetStyle(STYLE_BACKGROUND_OPA, 204); // 204 : value + view1->Resize(120, 50); // 120 : width 50 : height + group->Add(view1); + + container_->Add(group); + group->LayoutBottomToSibling("UIKit_DrawRect_Test_RectOpacity_002", 10); // 10 : offset size +} + +void UITestDrawRect::UIKit_DrawRect_Test_RectBorderColor_001() +{ + if (container_ == nullptr) { + return; + } + + UIViewGroup* group = CreateTestCaseGroup(); + group->SetViewId("UIKit_DrawRect_Test_RectBorderColor_001"); + + UILabel* label = CreateTitleLabel(); + label->SetText("设置不同边框颜色的矩形绘制 "); + group->Add(label); + + UIView* view = CreateUIView(); + view->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE, VIEW_DISTANCE_TO_TOP_SIDE); + view->SetStyle(STYLE_BORDER_COLOR, Color::Yellow().full); + view->SetStyle(STYLE_BORDER_WIDTH, 5); // 5 : value + + view->Resize(120, 50); // 120 : width 50 : height + group->Add(view); + + UIView* view1 = CreateUIView(); + view1->SetPosition(250, 50); // 250 : start x 50 : start y + view1->SetStyle(STYLE_BORDER_COLOR, Color::Red().full); + view1->SetStyle(STYLE_BORDER_WIDTH, 5); // 5 : value + view1->Resize(120, 50); // 120 : width 50 : height + group->Add(view1); + + container_->Add(group); + group->LayoutBottomToSibling("UIKit_DrawRect_Test_RectOpacity_003", 10); // 10 : offset size +} + +void UITestDrawRect::UIKit_DrawRect_Test_RectBorderWidth_001() +{ + if (container_ == nullptr) { + return; + } + + UIViewGroup* group = CreateTestCaseGroup(); + group->SetViewId("UIKit_DrawRect_Test_RectBorderWidth_001"); + + UILabel* label = CreateTitleLabel(); + label->SetText("设置边框宽度为零的矩形绘制 "); + group->Add(label); + + UIView* view = CreateUIView(); + view->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE, VIEW_DISTANCE_TO_TOP_SIDE); + view->SetStyle(STYLE_BORDER_WIDTH, 0); + view->Resize(120, 50); // 120 : width 50 : height + group->Add(view); + + container_->Add(group); + group->LayoutBottomToSibling("UIKit_DrawRect_Test_RectBorderColor_001", 10); // 10 : offset size +} + +void UITestDrawRect::UIKit_DrawRect_Test_RectBorderWidth_002() +{ + if (container_ == nullptr) { + return; + } + + UIViewGroup* group = CreateTestCaseGroup(); + group->SetViewId("UIKit_DrawRect_Test_RectBorderWidth_002"); + + UILabel* label = CreateTitleLabel(); + label->SetText("设置不同宽度边框大小的矩形绘制 "); + group->Add(label); + + UIView* view = CreateUIView(); + view->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE, VIEW_DISTANCE_TO_TOP_SIDE); + view->SetStyle(STYLE_BORDER_WIDTH, 5); // 5 : value + view->Resize(120, 50); // 120 : width 50 : height + group->Add(view); + + UIView* view1 = CreateUIView(); + view1->SetPosition(250, 50); // 250 : offset 50 : offset + view1->SetStyle(STYLE_BORDER_WIDTH, 10); // 10 : value + view1->Resize(120, 50); // 120 : width 50 : height + group->Add(view1); + + container_->Add(group); + group->LayoutBottomToSibling("UIKit_DrawRect_Test_RectBorderWidth_001", 10); // 10 : offset size +} + +void UITestDrawRect::UIKit_DrawRect_Test_RectBorderOpacity_001() +{ + if (container_ == nullptr) { + return; + } + + UIViewGroup* group = CreateTestCaseGroup(); + group->SetViewId("UIKit_DrawRect_Test_RectBorderOpacity_001"); + + UILabel* label = CreateTitleLabel(); + label->SetText("设置不透明边框矩形绘制:"); + group->Add(label); + + UIView* view = CreateUIView(); + view->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE, VIEW_DISTANCE_TO_TOP_SIDE); + view->SetStyle(STYLE_BORDER_WIDTH, 5); // 5 : value + view->SetStyle(STYLE_BORDER_OPA, OPA_OPAQUE); + view->Resize(120, 50); // 120 : width 50 : height + group->Add(view); + + container_->Add(group); + group->LayoutBottomToSibling("UIKit_DrawRect_Test_RectBorderWidth_002", 10); // 10 : offset size +} + +void UITestDrawRect::UIKit_DrawRect_Test_RectBorderOpacity_002() +{ + if (container_ == nullptr) { + return; + } + + UIViewGroup* group = CreateTestCaseGroup(); + group->SetViewId("UIKit_DrawRect_Test_RectBorderOpacity_002"); + + UILabel* label = CreateTitleLabel(); + label->SetText("设置全透明边框矩形绘制:"); + group->Add(label); + + UIView* view = CreateUIView(); + view->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE, VIEW_DISTANCE_TO_TOP_SIDE); + view->SetStyle(STYLE_BORDER_WIDTH, 5); // 5 : value + view->SetStyle(STYLE_BORDER_OPA, OPA_TRANSPARENT); + view->Resize(120, 50); // 120 : width 50 : height + group->Add(view); + + container_->Add(group); + group->LayoutBottomToSibling("UIKit_DrawRect_Test_RectBorderOpacity_001", 10); // 10 : offset size +} + +void UITestDrawRect::UIKit_DrawRect_Test_RectBorderOpacity_003() +{ + if (container_ == nullptr) { + return; + } + + UIViewGroup* group = CreateTestCaseGroup(); + group->SetViewId("UIKit_DrawRect_Test_RectBorderOpacity_003"); + + UILabel* label = CreateTitleLabel(); + label->SetText("设置不同透明度边框矩形绘制 "); + group->Add(label); + + UIView* view = CreateUIView(); + view->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE, VIEW_DISTANCE_TO_TOP_SIDE); + view->SetStyle(STYLE_BORDER_WIDTH, 5); // 5 : value + view->SetStyle(STYLE_BORDER_OPA, 153); // 153 : value + view->Resize(120, 50); // 120 : width 50 : height + group->Add(view); + + UIView* view1 = CreateUIView(); + view1->SetPosition(250, 50); // 250 : start x 50 : start y + view1->SetStyle(STYLE_BORDER_WIDTH, 5); // 5 : value + view1->SetStyle(STYLE_BORDER_OPA, 204); // 204 : value + view1->Resize(120, 50); // 120 : width 50 : height + group->Add(view1); + + container_->Add(group); + group->LayoutBottomToSibling("UIKit_DrawRect_Test_RectBorderOpacity_002", 10); // 10 : offset size +} + +void UITestDrawRect::UIKit_DrawRect_Test_RectPadding_001() +{ + if (container_ == nullptr) { + return; + } + + UIViewGroup* group = CreateTestCaseGroup(); + group->SetViewId("UIKit_DrawRect_Test_RectPadding_001"); + + UILabel* label = CreateTitleLabel(); + label->SetText("设置padding为零的矩形绘制 "); + group->Add(label); + + UIView* view = CreateUIView(); + view->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE, VIEW_DISTANCE_TO_TOP_SIDE); + view->SetStyle(STYLE_PADDING_LEFT, 0); + view->SetStyle(STYLE_PADDING_RIGHT, 0); + view->SetStyle(STYLE_PADDING_TOP, 0); + view->SetStyle(STYLE_PADDING_BOTTOM, 0); + view->Resize(120, 50); // 120 : width 50 : height + group->Add(view); + + container_->Add(group); + group->LayoutBottomToSibling("UIKit_DrawRect_Test_RectBorderOpacity_003", 10); // 10 : offset size +} + +void UITestDrawRect::UIKit_DrawRect_Test_RectPadding_002() +{ + if (container_ == nullptr) { + return; + } + + UIViewGroup* group = CreateTestCaseGroup(); + group->SetViewId("UIKit_DrawRect_Test_RectPadding_002"); + + UILabel* label = CreateTitleLabel(); + label->SetText("设置padding不为零的矩形绘制:"); + group->Add(label); + + UIView* view = CreateUIView(); + view->SetPosition(0, 50); // 0 : start x 50 : start y + view->Resize(100, 50); // 100 : width 50 : height + group->Add(view); + + UIView* view1 = CreateUIView(); + view1->SetPosition(120, 50); // 120 : start x 50 : start y + view1->SetStyle(STYLE_PADDING_LEFT, 10); // 10 : value + view1->SetStyle(STYLE_PADDING_RIGHT, 10); // 10 : value + view1->SetStyle(STYLE_PADDING_TOP, 10); // 10 : value + view1->SetStyle(STYLE_PADDING_BOTTOM, 10); // 10 : value + view1->Resize(120, 50); // 120 : width 50 : height + group->Add(view1); + + UIView* view2 = CreateUIView(); + view2->SetPosition(280, 50); // 280 : start x 50 : start y + view2->SetStyle(STYLE_PADDING_LEFT, 20); // 20 : value + view2->SetStyle(STYLE_PADDING_RIGHT, 10); // 10 : value + view2->SetStyle(STYLE_PADDING_TOP, 20); // 20 : value + view2->SetStyle(STYLE_PADDING_BOTTOM, 10); // 10 : value + view2->Resize(120, 50); // 120 : width 50 : height + group->Add(view2); + + container_->Add(group); + group->LayoutBottomToSibling("UIKit_DrawRect_Test_RectPadding_001", 10); // 10 : offset size +} + +void UITestDrawRect::UIKit_DrawRect_Test_RectMargin_001() +{ + if (container_ == nullptr) { + return; + } + + UIViewGroup* group = CreateTestCaseGroup(); + group->SetViewId("UIKit_DrawRect_Test_RectMargin_001"); + + UILabel* label = CreateTitleLabel(); + label->SetText("设置margin为零的矩形绘制 "); + group->Add(label); + + UIView* view = CreateUIView(); + view->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE, VIEW_DISTANCE_TO_TOP_SIDE); + view->SetStyle(STYLE_MARGIN_LEFT, 0); + view->SetStyle(STYLE_MARGIN_RIGHT, 0); + view->SetStyle(STYLE_MARGIN_TOP, 0); + view->SetStyle(STYLE_MARGIN_BOTTOM, 0); + view->Resize(120, 50); // 120 : width 50 : height + group->Add(view); + + container_->Add(group); + group->LayoutBottomToSibling("UIKit_DrawRect_Test_RectPadding_002", 10); // 10 : offset size +} + +void UITestDrawRect::UIKit_DrawRect_Test_RectMargin_002() +{ + if (container_ == nullptr) { + return; + } + + UIViewGroup* group = CreateTestCaseGroup(); + group->SetViewId("UIKit_DrawRect_Test_RectMargin_002"); + + UILabel* label = CreateTitleLabel(); + label->SetText("设置margin不为零的矩形绘制:"); + group->Add(label); + + UIView* view = CreateUIView(); + view->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE, VIEW_DISTANCE_TO_TOP_SIDE); + view->SetStyle(STYLE_MARGIN_LEFT, 10); // 10 : margin left + view->SetStyle(STYLE_MARGIN_RIGHT, 10); // 10 : margin right + view->SetStyle(STYLE_MARGIN_TOP, 10); // 10 : margin top + view->SetStyle(STYLE_MARGIN_BOTTOM, 10); // 10 : margin bottom + view->Resize(120, 50); // 120 : width 50 : height + group->Add(view); + + UIView* view1 = CreateUIView(); + view1->SetPosition(250, 50); // 250 : start x 50 : start y + view1->SetStyle(STYLE_MARGIN_LEFT, 20); // 20 : margin left + view1->SetStyle(STYLE_MARGIN_RIGHT, 10); // 10 : margin right + view1->SetStyle(STYLE_MARGIN_TOP, 20); // 20 : margin top + view1->SetStyle(STYLE_MARGIN_BOTTOM, 10); // 10 : margin bottom + view1->Resize(120, 50); // 120 : width 50 : height + group->Add(view1); + + container_->Add(group); + group->LayoutBottomToSibling("UIKit_DrawRect_Test_RectMargin_001", 10); // 10 : offset size +} + +void UITestDrawRect::UIKit_DrawRect_Test_RectPaddingMargin_001() +{ + if (container_ == nullptr) { + return; + } + + UIViewGroup* group = CreateTestCaseGroup(); + group->SetViewId("UIKit_DrawRect_Test_RectPaddingMargin_001"); + + UILabel* label = CreateTitleLabel(); + label->SetText("设置 padding/margin 均为零的矩形绘制:"); + group->Add(label); + + UIView* view = CreateUIView(); + view->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE, VIEW_DISTANCE_TO_TOP_SIDE); + view->SetStyle(STYLE_MARGIN_LEFT, 0); + view->SetStyle(STYLE_MARGIN_RIGHT, 0); + view->SetStyle(STYLE_MARGIN_TOP, 0); + view->SetStyle(STYLE_MARGIN_BOTTOM, 0); + view->SetStyle(STYLE_PADDING_LEFT, 0); + view->SetStyle(STYLE_PADDING_RIGHT, 0); + view->SetStyle(STYLE_PADDING_TOP, 0); + view->SetStyle(STYLE_PADDING_BOTTOM, 0); + view->Resize(120, 50); // 120 : width 50 : height + group->Add(view); + + container_->Add(group); + group->LayoutBottomToSibling("UIKit_DrawRect_Test_RectMargin_002", 10); // 10 : offset size +} + +void UITestDrawRect::UIKit_DrawRect_Test_RectPaddingMargin_002() +{ + if (container_ == nullptr) { + return; + } + + UIViewGroup* group = CreateTestCaseGroup(); + group->SetViewId("UIKit_DrawRect_Test_RectPaddingMargin_002"); + + UILabel* label = CreateTitleLabel(); + label->SetText("设置padding/margin均不为零的矩形绘制 "); + group->Add(label); + + UIView* view = CreateUIView(); + view->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE, VIEW_DISTANCE_TO_TOP_SIDE); + view->SetStyle(STYLE_MARGIN_LEFT, 0); + view->SetStyle(STYLE_MARGIN_RIGHT, 0); + view->SetStyle(STYLE_MARGIN_TOP, 0); + view->SetStyle(STYLE_MARGIN_BOTTOM, 0); + view->SetStyle(STYLE_PADDING_LEFT, 0); + view->SetStyle(STYLE_PADDING_RIGHT, 0); + view->SetStyle(STYLE_PADDING_TOP, 0); + view->SetStyle(STYLE_PADDING_BOTTOM, 0); + view->Resize(120, 50); // 120 : width 50 : height + group->Add(view); + + UIView* view1 = CreateUIView(); + view1->SetPosition(250, 50); // 250 : start 50 : start + view1->SetStyle(STYLE_MARGIN_LEFT, 10); // 10 : margin left + view1->SetStyle(STYLE_MARGIN_RIGHT, 10); // 10 : margin right + view1->SetStyle(STYLE_MARGIN_TOP, 10); // 10 : margin top + view1->SetStyle(STYLE_MARGIN_BOTTOM, 10); // 10 : margin bottom + view1->SetStyle(STYLE_PADDING_LEFT, 10); // 10 : padding left + view1->SetStyle(STYLE_PADDING_RIGHT, 10); // 10 : padding right + view1->SetStyle(STYLE_PADDING_TOP, 10); // 10 : padding top + view1->SetStyle(STYLE_PADDING_BOTTOM, 10); // 10 : padding bottom + view1->Resize(120, 50); // 120 : width 50 : height + group->Add(view1); + + container_->Add(group); + group->LayoutBottomToSibling("UIKit_DrawRect_Test_RectPaddingMargin_001", 10); // 10 : offset size +} + +void UITestDrawRect::UIKit_DrawRect_Test_RectWidthAndHeight_001() +{ + if (container_ == nullptr) { + return; + } + + UIViewGroup* group = CreateTestCaseGroup(); + group->SetViewId("UIKit_DrawRect_Test_RectWidthAndHeight_001"); + + UILabel* label = CreateTitleLabel(); + label->SetText("设置宽度为零的矩形绘制 "); + group->Add(label); + + UIView* view = CreateUIView(); + view->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE, VIEW_DISTANCE_TO_TOP_SIDE); + view->SetStyle(STYLE_BORDER_WIDTH, 0); + view->SetStyle(STYLE_BORDER_RADIUS, 10); // 10 : border radius + view->Resize(0, 50); // 0 : width 50 : height + container_->Add(view); + + container_->Add(group); + group->LayoutBottomToSibling("UIKit_DrawRect_Test_RectPaddingMargin_002", 20); // 20 : offset size +} + +void UITestDrawRect::UIKit_DrawRect_Test_RectWidthAndHeight_002() +{ + if (container_ == nullptr) { + return; + } + + UIViewGroup* group = CreateTestCaseGroup(); + group->SetViewId("UIKit_DrawRect_Test_RectWidthAndHeight_002"); + + UILabel* label = CreateTitleLabel(); + label->SetText("设置高度为零的矩形绘制 "); + group->Add(label); + + UIView* view = CreateUIView(); + view->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE, VIEW_DISTANCE_TO_TOP_SIDE); + view->SetStyle(STYLE_BORDER_WIDTH, 0); // 10 : value + view->SetStyle(STYLE_BORDER_RADIUS, 0); // 10 : value + view->Resize(120, 0); // 120 : width 0 : height + group->Add(view); + + container_->Add(group); + group->LayoutBottomToSibling("UIKit_DrawRect_Test_RectWidthAndHeight_001", 20); // 20 : offset size +} + +void UITestDrawRect::UIKit_DrawRect_Test_RectWidthAndHeight_003() +{ + if (container_ == nullptr) { + return; + } + + UIViewGroup* group = CreateTestCaseGroup(); + group->SetViewId("UIKit_DrawRect_Test_RectWidthAndHeight_003"); + + UILabel* label = CreateTitleLabel(); + label->SetText("设置宽度和高度都为零的矩形绘制 "); + group->Add(label); + + UIView* view = CreateUIView(); + view->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE, VIEW_DISTANCE_TO_TOP_SIDE); + view->SetStyle(STYLE_BORDER_WIDTH, 0); + view->SetStyle(STYLE_BORDER_RADIUS, 10); // 10 : border radius + view->Resize(0, 0); // 0 : width 0 : height + group->Add(view); + + container_->Add(group); + group->LayoutBottomToSibling("UIKit_DrawRect_Test_RectWidthAndHeight_002", 20); // 20 : offset size +} +} // namespace OHOS diff --git a/test/uitest/test_draw_rect/ui_test_draw_rect.h b/test/uitest/test_draw_rect/ui_test_draw_rect.h new file mode 100755 index 0000000..8ab7732 --- /dev/null +++ b/test/uitest/test_draw_rect/ui_test_draw_rect.h @@ -0,0 +1,184 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef UI_TEST_DRAW_RECT_H +#define UI_TEST_DRAW_RECT_H + +#include "components/ui_button.h" +#include "components/ui_label.h" +#include "components/ui_scroll_view.h" +#include "ui_test.h" + +namespace OHOS { +class UITestDrawRect : public UITest { +public: + UITestDrawRect() {} + ~UITestDrawRect() {} + void SetUp() override; + void TearDown() override; + UIView* GetTestView() override; + + void UIKit_DrawRect_Test_RectNoBorder_001(); + void UIKit_DrawRect_Test_RectNoBorder_002(); + void UIKit_DrawRect_Test_RectNoBorder_003(); + void UIKit_DrawRect_Test_RectNoBorder_004(); + void UIKit_DrawRect_Test_RectNoBorder_005(); + void UIKit_DrawRect_Test_RectNoBorder_006(); + void UIKit_DrawRect_Test_RectNoBorder_007(); + void UIKit_DrawRect_Test_RectNoBorder_008(); + void UIKit_DrawRect_Test_RectNoBorder_009(); + void UIKit_DrawRect_Test_RectNoBorder_0010(); + void UIKit_DrawRect_Test_RectBorderNoRadius_001(); + void UIKit_DrawRect_Test_RectBorderNoRadius_002(); + void UIKit_DrawRect_Test_RectBorderRadius_001(); + void UIKit_DrawRect_Test_RectBorderRadius_002(); + void UIKit_DrawRect_Test_RectBorderRadius_003(); + void UIKit_DrawRect_Test_RectBorderRadius_004(); + void UIKit_DrawRect_Test_RectBorderRadius_005(); + void UIKit_DrawRect_Test_RectBorderRadius_006(); + void UIKit_DrawRect_Test_RectBorderRadius_007(); + void UIKit_DrawRect_Test_RectBorderRadius_008(); + void UIKit_DrawRect_Test_RectBorderRadius_009(); + void UIKit_DrawRect_Test_RectBorderRadius_010(); + void UIKit_DrawRect_Test_RectBorderRadius_011(); + + /** + * @brief Test draw rect function + */ + void UIKit_DrawRect_Test_Rect_001(); + + /** + * @brief Test draw rect background color + */ + void UIKit_DrawRect_Test_RectColor_001(); + + /** + * @brief Test draw rect radius is 0 + */ + void UIKit_DrawRect_Test_RectRadius_001(); + + /** + * @brief Test draw rect radius + */ + void UIKit_DrawRect_Test_RectRadius_002(); + + /** + * @brief Test draw rect radius equal width + */ + void UIKit_DrawRect_Test_RectRadius_003(); + + /** + * @brief Test draw rect radius equal width and height + */ + void UIKit_DrawRect_Test_RectRadius_004(); + + /** + * @brief Test draw rect opacity is not transparent + */ + void UIKit_DrawRect_Test_RectOpacity_001(); + + /** + * @brief Test draw rect opacity is transparent + */ + void UIKit_DrawRect_Test_RectOpacity_002(); + + /** + * @brief Test draw rect opacity with different value + */ + void UIKit_DrawRect_Test_RectOpacity_003(); + + /** + * @brief Test draw rect border color with different value + */ + void UIKit_DrawRect_Test_RectBorderColor_001(); + + /** + * @brief Test draw rect border width is 0 + */ + void UIKit_DrawRect_Test_RectBorderWidth_001(); + + /** + * @brief Test draw rect border with different value + */ + void UIKit_DrawRect_Test_RectBorderWidth_002(); + + /** + * @brief Test draw rect border opacity is not transparent + */ + void UIKit_DrawRect_Test_RectBorderOpacity_001(); + + /** + * @brief Test draw rect border opacity is transparent + */ + void UIKit_DrawRect_Test_RectBorderOpacity_002(); + + /** + * @brief Test draw rect border opacity with different value + */ + void UIKit_DrawRect_Test_RectBorderOpacity_003(); + + /** + * @brief Test draw rect padding is 0 + */ + void UIKit_DrawRect_Test_RectPadding_001(); + + /** + * @brief Test draw rect padding with different value + */ + void UIKit_DrawRect_Test_RectPadding_002(); + + /** + * @brief Test draw rect margin is 0 + */ + void UIKit_DrawRect_Test_RectMargin_001(); + + /** + * @brief Test draw rect margin is not 0 + */ + void UIKit_DrawRect_Test_RectMargin_002(); + + /** + * @brief Test draw rect padding and margin is 0 + */ + void UIKit_DrawRect_Test_RectPaddingMargin_001(); + + /** + * @brief Test draw rect padding and margin with different value + */ + void UIKit_DrawRect_Test_RectPaddingMargin_002(); + + /** + * @brief Test rect width is 0 + */ + void UIKit_DrawRect_Test_RectWidthAndHeight_001(); + + /** + * @brief Test rect height is 0 + */ + void UIKit_DrawRect_Test_RectWidthAndHeight_002(); + + /** + * @brief Test rect width and height is 0 + */ + void UIKit_DrawRect_Test_RectWidthAndHeight_003(); + +private: + UIViewGroup* CreateTestCaseGroup() const; + UILabel* CreateTitleLabel() const; + UIView* CreateUIView() const; + UIScrollView* container_ = nullptr; +}; +} // namespace OHOS +#endif // UI_TEST_DRAW_RECT_H diff --git a/test/uitest/test_event_injector/ui_test_event_injector.cpp b/test/uitest/test_event_injector/ui_test_event_injector.cpp new file mode 100755 index 0000000..efda267 --- /dev/null +++ b/test/uitest/test_event_injector/ui_test_event_injector.cpp @@ -0,0 +1,472 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "graphic_config.h" + +#if ENABLE_DEBUG +#include "common/screen.h" +#include "components/root_view.h" +#include "dfx/event_injector.h" +#include "ui_test_event_injector.h" +#include +#if ENABLE_WINDOW +#include "window/window.h" +#endif + +namespace OHOS { +namespace { + const int16_t ITEM_H = 50; + const int16_t TEXT_H = 29; + const int16_t TEXT_W = 250; + const int16_t TEST_VIEW_H = 50; + const int16_t TEST_VIEW_W = 50; + const int16_t GAP = 5; + const int16_t TEST_VIEW_GAP = 80; + const int16_t TEST_BUTTON_W = 100; + const int16_t TEST_BUTTON_H = 30; + const int16_t LAYOUT_HEIGHT = 150; + const int16_t LAYOUT_WIDTH = 480; + const int16_t BLANK = 20; + const int16_t SCROLL_WIDTH = 300; + const int16_t SCROLL_HEIGHT = 300; + const int16_t SCROLL_BUTTON_W = 800; + const int16_t SCROLL_BUTTON_H = 400; + const int16_t DRAG_TIME_OFFSET = 20; + const int16_t RATIO_X = 3; + const int16_t RATIO_Y = 10; + const int16_t POINT_OFFSET = 4; +} + +class TestEventInjectorView : public UIView, public RootView::OnKeyActListener { +public: + TestEventInjectorView() : label_(nullptr) {} + virtual ~TestEventInjectorView() {} + + void InitListener() + { + RootView::GetInstance()->SetOnKeyActListener(this); + } + + bool OnLongPressEvent(const LongPressEvent& event) override + { + if (label_ != nullptr) { + label_->SetText("long press!"); + label_->Invalidate(); + } + return UIView::OnLongPressEvent(event); + } + + bool OnDragEvent(const DragEvent& event) override + { + if (label_ != nullptr) { + label_->SetText("drag!"); + label_->Invalidate(); + } + return UIView::OnDragEvent(event); + } + + void SetSentence(const char* sentence) + { + sentence_ = sentence; + } + + bool OnClickEvent(const ClickEvent& event) override + { + if (label_ != nullptr) { + label_->SetText(sentence_); + label_->Invalidate(); + } + return UIView::OnClickEvent(event); + } + + bool OnPressEvent(const PressEvent& event) override + { + if (label_ != nullptr) { + label_->SetText("press!"); + label_->Invalidate(); + } + return UIView::OnPressEvent(event); + } + + bool OnReleaseEvent(const ReleaseEvent& event) override + { + if (label_ != nullptr) { + label_->SetText("release!"); + label_->Invalidate(); + } + return UIView::OnReleaseEvent(event); + } + + bool OnCancelEvent(const CancelEvent& event) override + { + if (label_ != nullptr) { + label_->SetText("cancel!"); + label_->Invalidate(); + } + return UIView::OnCancelEvent(event); + } + + void SetLabel(UILabel* label) + { + label_ = label; + } + + bool OnKeyAct(UIView& view, const KeyEvent& event) override + { + if (label_ == nullptr) { + return false; + } + label_->SetText("key!"); + label_->Invalidate(); + return true; + } + +private: + UILabel* label_; + const char* sentence_ = "click"; +}; + + +void UITestEventInjector::SetUp() +{ + if (container_ == nullptr) { + container_ = new UIScrollView(); + container_->Resize(Screen::GetInstance().GetWidth(), Screen::GetInstance().GetHeight() - BACK_BUTTON_HEIGHT); + container_->SetHorizontalScrollState(false); + container_->SetThrowDrag(true); + } + EventInjector::GetInstance()->RegisterEventInjector(EventDataType::POINT_TYPE); + EventInjector::GetInstance()->RegisterEventInjector(EventDataType::KEY_TYPE); + +#if ENABLE_WINDOW + Window* window = RootView::GetInstance()->GetBoundWindow(); + if (window != nullptr) { + EventInjector::GetInstance()->SetWindowId(window->GetWindowId()); + } +#endif +} + +void UITestEventInjector::TearDown() +{ + DeleteChildren(container_); + container_ = nullptr; + layout_ = nullptr; + positionX_ = 20; // 20 : start x + positionY_ = 20; // 20 : start y + if (EventInjector::GetInstance()->IsEventInjectorRegistered(EventDataType::POINT_TYPE)) { + EventInjector::GetInstance()->UnregisterEventInjector(EventDataType::POINT_TYPE); + } + if (EventInjector::GetInstance()->IsEventInjectorRegistered(EventDataType::KEY_TYPE)) { + EventInjector::GetInstance()->UnregisterEventInjector(EventDataType::KEY_TYPE); + } +} + +UIView* UITestEventInjector::GetTestView() +{ + UIKit_Event_Injector_Click_Event_001(); + UIKit_Event_Injector_Drag_Event_002(); + UIKit_Event_Injector_Long_Press_Event_003(); + UIKit_Event_Injector_Key_Event_004(); + + SetUpScrollView(); + UIKit_Event_Injector_Up_to_Down_005(); + UIKit_Event_Injector_Down_to_Up_006(); + UIKit_Event_Injector_Left_to_Right_007(); + UIKit_Event_Injector_Right_to_Left_008(); + UIKit_Event_Injector_ULeft_to_LRight_009(); + UIKit_Event_Injector_LRight_to_ULeft_010(); + IncreaseDragTime(); + DecreaseDragTime(); + DragTimeDisplay(); + + layout_->LayoutChildren(); + return container_; +} + +void UITestEventInjector::UIKit_Event_Injector_Click_Event_001() +{ + clickBtn_ = new UILabelButton(); + InnerTest("模拟点击事件 ", true, false, false, "click", clickBtn_, clickTestView_); +} + +void UITestEventInjector::UIKit_Event_Injector_Drag_Event_002() +{ + dragBtn_ = new UILabelButton(); + InnerTest("模拟滑动事件 ", true, true, false, "drag", dragBtn_, dragTestView_); +} + +void UITestEventInjector::UIKit_Event_Injector_Long_Press_Event_003() +{ + longPressBtn_ = new UILabelButton(); + InnerTest("模拟长按事件 ", true, true, true, "long press", longPressBtn_, longPressTestView_); +} + +void UITestEventInjector::UIKit_Event_Injector_Key_Event_004() +{ + keyBtn_ = new UILabelButton(); + InnerTest("模拟按键输入 ", true, false, false, "key event", keyBtn_, KeyEventTestView_); +} + +void UITestEventInjector::UIKit_Event_Injector_Up_to_Down_005() +{ + upToDownBtn_ = new UILabelButton(); + SetUpButton(upToDownBtn_, "up to down"); +} + +void UITestEventInjector::UIKit_Event_Injector_Down_to_Up_006() +{ + downToUpBtn_ = new UILabelButton(); + SetUpButton(downToUpBtn_, "down to up"); +} + +void UITestEventInjector::UIKit_Event_Injector_Left_to_Right_007() +{ + leftToRightBtn_ = new UILabelButton(); + SetUpButton(leftToRightBtn_, "left to right"); +} + +void UITestEventInjector::UIKit_Event_Injector_Right_to_Left_008() +{ + rightToLeftBtn_ = new UILabelButton(); + SetUpButton(rightToLeftBtn_, "right to left"); +} + +void UITestEventInjector::UIKit_Event_Injector_ULeft_to_LRight_009() +{ + uLeftTolRightBtn_ = new UILabelButton(); + SetUpButton(uLeftTolRightBtn_, "uLeft to lRight"); +} + +void UITestEventInjector::UIKit_Event_Injector_LRight_to_ULeft_010() +{ + lRightTouLeftBtn_ = new UILabelButton(); + SetUpButton(lRightTouLeftBtn_, "lRight to uleft"); +} + +void UITestEventInjector::IncreaseDragTime() +{ + increaseDragTimeBtn_ = new UILabelButton(); + SetUpButton(increaseDragTimeBtn_, "increase drag time"); +} + +void UITestEventInjector::DecreaseDragTime() +{ + decreaseDragTimeBtn_ = new UILabelButton(); + SetUpButton(decreaseDragTimeBtn_, "decrease drag time"); +} + +void UITestEventInjector::DragTimeDisplay() +{ + DragTimeDisplayBtn_ = new UILabelButton(); + std::string dragTimestr = "dragTime:" + std::to_string(dragTime_); + SetUpButton(DragTimeDisplayBtn_, dragTimestr.c_str()); +} + +void UITestEventInjector::InnerTest(const char* title, + bool touchable, + bool draggable, + bool dragParent, + const char* btnTitle, + UILabelButton* btn, + TestEventInjectorView*& testView) +{ + if ((container_ != nullptr) && (btn != nullptr)) { + UILabel* label = new UILabel(); + container_->Add(label); + label->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE, positionY_, Screen::GetInstance().GetWidth(), + TITLE_LABEL_DEFAULT_HEIGHT); + label->SetText(title); + label->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); + positionY_ += (TEXT_H + GAP); + testView = new TestEventInjectorView(); + testView->InitListener(); + container_->Add(testView); + testView->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE, positionY_, TEST_VIEW_W, TEST_VIEW_H); + testView->SetStyle(STYLE_BACKGROUND_COLOR, Color::Blue().full); + testView->SetTouchable(touchable); + testView->SetDraggable(draggable); + testView->SetDragParentInstead(dragParent); + UILabel* label1 = new UILabel(); + container_->Add(label1); + label1->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE + TEST_VIEW_GAP, + positionY_ + 2 * GAP, TEXT_W, TEXT_H); // 2 : ratio + label1->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); + testView->SetLabel(label1); + + container_->Add(btn); + btn->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE + 3 * TEST_VIEW_GAP, positionY_ + GAP, // 3 : ratio + BUTTON_WIDHT2, BUTTON_HEIGHT2); + btn->SetText(btnTitle); + btn->SetFont(DEFAULT_VECTOR_FONT_FILENAME, BUTTON_LABEL_SIZE); + btn->SetOnClickListener(this); + btn->SetStyleForState(STYLE_BORDER_RADIUS, BUTTON_STYLE_BORDER_RADIUS_VALUE, UIButton::RELEASED); + btn->SetStyleForState(STYLE_BORDER_RADIUS, BUTTON_STYLE_BORDER_RADIUS_VALUE, UIButton::PRESSED); + btn->SetStyleForState(STYLE_BORDER_RADIUS, BUTTON_STYLE_BORDER_RADIUS_VALUE, UIButton::INACTIVE); + btn->SetStyleForState(STYLE_BACKGROUND_COLOR, BUTTON_STYLE_BACKGROUND_COLOR_VALUE, UIButton::RELEASED); + btn->SetStyleForState(STYLE_BACKGROUND_COLOR, BUTTON_STYLE_BACKGROUND_COLOR_VALUE, UIButton::PRESSED); + btn->SetStyleForState(STYLE_BACKGROUND_COLOR, BUTTON_STYLE_BACKGROUND_COLOR_VALUE, UIButton::INACTIVE); + + positionY_ += ITEM_H; + } +} + +void UITestEventInjector::SetUpScrollView() +{ + if (container_ == nullptr) { + return; + } + UILabel* label = GetTitleLabel("模拟Drag事件测试"); + container_->Add(label); + label->SetPosition(TEXT_DISTANCE_TO_LEFT_SIDE, positionY_); + SetLastPos(label); + + scrollTestView_ = new UIScrollView(); + scrollTestView_->SetStyle(STYLE_BACKGROUND_COLOR, Color::Red().full); + scrollTestView_->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE, positionY_, SCROLL_WIDTH, SCROLL_HEIGHT); + scrollTestView_->SetXScrollBarVisible(true); + scrollTestView_->SetYScrollBarVisible(true); + scrollTestView_->SetThrowDrag(true); + container_->Add(scrollTestView_); + UILabelButton* button1 = new UILabelButton(); + button1->SetText("button1"); + button1->SetPosition(0, 0, SCROLL_BUTTON_W, SCROLL_BUTTON_H); + UILabelButton* button2 = new UILabelButton(); + button2->SetText("button2"); + button2->SetPosition(0, SCROLL_BUTTON_H, SCROLL_BUTTON_W, SCROLL_BUTTON_H); + scrollTestView_->Add(button1); + scrollTestView_->Add(button2); + + if (layout_ == nullptr) { + layout_ = new GridLayout(); + layout_->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE + SCROLL_WIDTH + GAP, positionY_, + LAYOUT_WIDTH, LAYOUT_HEIGHT); + container_->Add(layout_); + layout_->SetLayoutDirection(LAYOUT_VER); + layout_->SetRows(3); // 3 : rows + layout_->SetCols(3); // 3 : columns + } +} + +void UITestEventInjector::SetLastPos(UIView* view) +{ + if (view == nullptr) { + return; + } + lastX_ = view->GetX(); + lastY_ = view->GetY() + view->GetHeight(); + positionY_ = lastY_ + 8 * GAP; /* 8:ratio */ +} + +void UITestEventInjector::SetUpButton(UILabelButton* btn, const char* title) +{ + if (btn == nullptr) { + return; + } + layout_->Add(btn); + btn->Resize(BUTTON_WIDHT3, BUTTON_HEIGHT3); + btn->SetText(title); + btn->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); + btn->SetOnClickListener(this); + btn->SetStyleForState(STYLE_BORDER_RADIUS, BUTTON_STYLE_BORDER_RADIUS_VALUE, UIButton::RELEASED); + btn->SetStyleForState(STYLE_BORDER_RADIUS, BUTTON_STYLE_BORDER_RADIUS_VALUE, UIButton::PRESSED); + btn->SetStyleForState(STYLE_BORDER_RADIUS, BUTTON_STYLE_BORDER_RADIUS_VALUE, UIButton::INACTIVE); + btn->SetStyleForState(STYLE_BACKGROUND_COLOR, BUTTON_STYLE_BACKGROUND_COLOR_VALUE, UIButton::RELEASED); + btn->SetStyleForState(STYLE_BACKGROUND_COLOR, BUTTON_STYLE_BACKGROUND_COLOR_VALUE, UIButton::PRESSED); + btn->SetStyleForState(STYLE_BACKGROUND_COLOR, BUTTON_STYLE_BACKGROUND_COLOR_VALUE, UIButton::INACTIVE); +} + +void UITestEventInjector::SetDragTimeDisplay(uint16_t dragTime) +{ + std::string dragTimestr = "dragTime:" + std::to_string(dragTime); + DragTimeDisplayBtn_->SetText(dragTimestr.c_str()); + DragTimeDisplayBtn_->Invalidate(); +} + +/* drag range:0 < x < 300, 62 < y < 362, click range:20 < x < 60, 392 < y < 432 */ +bool UITestEventInjector::OnClick(UIView& view, const ClickEvent& event) +{ + Point point; + Point scrollPoint; + if (&view == clickBtn_) { + point = {static_cast(clickTestView_->GetRect().GetX() + TEST_VIEW_W / POINT_OFFSET), + clickBtn_->GetRect().GetBottom()}; + EventInjector::GetInstance()->SetClickEvent(point); + } else if (&view == dragBtn_) { + point = {static_cast(dragTestView_->GetRect().GetX() + TEST_VIEW_W / POINT_OFFSET), + dragBtn_->GetRect().GetBottom()}; + Point endPoint = {static_cast(point.x + (RATIO_X * TEST_VIEW_W) / POINT_OFFSET), point.y}; + // 80:ms + EventInjector::GetInstance()->SetDragEvent(point, endPoint, 80); + } else if (&view == longPressBtn_) { + point = {static_cast(longPressTestView_->GetRect().GetX() + TEST_VIEW_W / POINT_OFFSET), + longPressBtn_->GetRect().GetBottom()}; + EventInjector::GetInstance()->SetLongPressEvent(point); + } else if (&view == keyBtn_) { + // 26:key id + uint16_t keyId = 26; + EventInjector::GetInstance()->SetKeyEvent(keyId, InputDevice::STATE_PRESS); + } else if (&view == upToDownBtn_) { + scrollPoint = {scrollTestView_->GetRect().GetX(), scrollTestView_->GetRect().GetY()}; + Point startPoint = {static_cast(scrollPoint.x + SCROLL_WIDTH / RATIO_X), + static_cast(scrollPoint.y + SCROLL_HEIGHT / RATIO_Y)}; + Point endPoint = {static_cast(scrollPoint.x + SCROLL_WIDTH / RATIO_X), + static_cast(scrollPoint.y + SCROLL_HEIGHT / RATIO_X)}; + EventInjector::GetInstance()->SetDragEvent(startPoint, endPoint, dragTime_); + } else if (&view == downToUpBtn_) { + scrollPoint = {scrollTestView_->GetRect().GetX(), scrollTestView_->GetRect().GetY()}; + Point startPoint = {static_cast(scrollPoint.x + SCROLL_WIDTH / RATIO_X), + static_cast(scrollPoint.y + SCROLL_HEIGHT / RATIO_X)}; + Point endPoint = {static_cast(scrollPoint.x + SCROLL_WIDTH / RATIO_X), + static_cast(scrollPoint.y + SCROLL_HEIGHT / RATIO_Y)}; + EventInjector::GetInstance()->SetDragEvent(startPoint, endPoint, dragTime_); + } else if (&view == leftToRightBtn_) { + scrollPoint = {scrollTestView_->GetRect().GetX(), scrollTestView_->GetRect().GetY()}; + Point startPoint = {static_cast(scrollPoint.x + SCROLL_WIDTH / RATIO_Y), + static_cast(scrollPoint.y + SCROLL_HEIGHT / RATIO_X)}; + Point endPoint = {static_cast(scrollPoint.x + SCROLL_WIDTH / RATIO_X), + static_cast(scrollPoint.y + SCROLL_HEIGHT / RATIO_X)}; + EventInjector::GetInstance()->SetDragEvent(startPoint, endPoint, dragTime_); + } else if (&view == rightToLeftBtn_) { + scrollPoint = {scrollTestView_->GetRect().GetX(), scrollTestView_->GetRect().GetY()}; + Point startPoint = {static_cast(scrollPoint.x + SCROLL_WIDTH / RATIO_X), + static_cast(scrollPoint.y + SCROLL_HEIGHT / RATIO_X)}; + Point endPoint = {static_cast(scrollPoint.x + SCROLL_WIDTH / RATIO_Y), + static_cast(scrollPoint.y + SCROLL_HEIGHT / RATIO_X)}; + EventInjector::GetInstance()->SetDragEvent(startPoint, endPoint, dragTime_); + } else if (&view == uLeftTolRightBtn_) { + scrollPoint = {scrollTestView_->GetRect().GetX(), scrollTestView_->GetRect().GetY()}; + Point startPoint = {static_cast(scrollPoint.x + SCROLL_WIDTH / RATIO_Y), + static_cast(scrollPoint.y + SCROLL_HEIGHT / RATIO_Y)}; + Point endPoint = {static_cast(scrollPoint.x + SCROLL_WIDTH / RATIO_X), + static_cast(scrollPoint.y + SCROLL_HEIGHT / RATIO_X)}; + EventInjector::GetInstance()->SetDragEvent(startPoint, endPoint, dragTime_); + } else if (&view == lRightTouLeftBtn_) { + scrollPoint = {scrollTestView_->GetRect().GetX(), scrollTestView_->GetRect().GetY()}; + Point startPoint = {static_cast(scrollPoint.x + SCROLL_WIDTH / RATIO_X), + static_cast(scrollPoint.y + SCROLL_HEIGHT / RATIO_X)}; + Point endPoint = {static_cast(scrollPoint.x + SCROLL_WIDTH / RATIO_Y), + static_cast(scrollPoint.y + SCROLL_HEIGHT / RATIO_Y)}; + EventInjector::GetInstance()->SetDragEvent(startPoint, endPoint, dragTime_); + } else if (&view == increaseDragTimeBtn_) { + dragTime_ += DRAG_TIME_OFFSET; + SetDragTimeDisplay(dragTime_); + } else if (&view == decreaseDragTimeBtn_) { + dragTime_ -= DRAG_TIME_OFFSET; + SetDragTimeDisplay(dragTime_); + } + return true; +} +} // namespace OHOS +#endif // ENABLE_DEBUG \ No newline at end of file diff --git a/test/uitest/test_event_injector/ui_test_event_injector.h b/test/uitest/test_event_injector/ui_test_event_injector.h new file mode 100755 index 0000000..ba9507c --- /dev/null +++ b/test/uitest/test_event_injector/ui_test_event_injector.h @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef UI_TEST_EVENT_INJECTOR_H +#define UI_TEST_EVENT_INJECTOR_H + +#include "graphic_config.h" + +#if ENABLE_DEBUG +#include "components/root_view.h" +#include "components/ui_label.h" +#include "components/ui_label_button.h" +#include "components/ui_scroll_view.h" +#include "dock/input_device.h" +#include "ui_test.h" +#include "layout/grid_layout.h" + +namespace OHOS { +class TestEventInjectorView; +class UITestEventInjector : public UITest, public UIView::OnClickListener { +public: + UITestEventInjector() {} + ~UITestEventInjector() {} + void SetUp() override; + void TearDown() override; + UIView* GetTestView() override; + bool OnClick(UIView& view, const ClickEvent& event) override; + + void UIKit_Event_Injector_Click_Event_001(); + void UIKit_Event_Injector_Drag_Event_002(); + void UIKit_Event_Injector_Long_Press_Event_003(); + void UIKit_Event_Injector_Key_Event_004(); + void UIKit_Event_Injector_Up_to_Down_005(); + void UIKit_Event_Injector_Down_to_Up_006(); + void UIKit_Event_Injector_Left_to_Right_007(); + void UIKit_Event_Injector_Right_to_Left_008(); + void UIKit_Event_Injector_ULeft_to_LRight_009(); + void UIKit_Event_Injector_LRight_to_ULeft_010(); + +private: + UIScrollView* container_ = nullptr; + GridLayout* layout_ = nullptr; + UILabelButton* clickBtn_ = nullptr; + UILabelButton* dragBtn_ = nullptr; + UILabelButton* longPressBtn_ = nullptr; + UILabelButton* keyBtn_ = nullptr; + UILabelButton* upToDownBtn_ = nullptr; + UILabelButton* downToUpBtn_ = nullptr; + UILabelButton* leftToRightBtn_ = nullptr; + UILabelButton* rightToLeftBtn_ = nullptr; + UILabelButton* uLeftTolRightBtn_ = nullptr; + UILabelButton* lRightTouLeftBtn_ = nullptr; + UILabelButton* increaseDragTimeBtn_ = nullptr; + UILabelButton* decreaseDragTimeBtn_ = nullptr; + UILabelButton* DragTimeDisplayBtn_ = nullptr; + TestEventInjectorView* clickTestView_ = nullptr; + TestEventInjectorView* dragTestView_ = nullptr; + TestEventInjectorView* longPressTestView_ = nullptr; + TestEventInjectorView* KeyEventTestView_ = nullptr; + UIScrollView* scrollTestView_ = nullptr; + + int16_t lastX_ = 0; + int16_t lastY_ = 0; + uint16_t dragTime_ = 100; // 100: 100ms + + void InnerTest(const char* title, bool touchable, bool draggable, bool dragParent, + const char* btnTitle, UILabelButton* btn, TestEventInjectorView*& testView); + void SetLastPos(UIView* view); + void SetUpButton(UILabelButton* btn, const char* title); + void SetUpScrollView(); + void IncreaseDragTime(); + void DecreaseDragTime(); + void DragTimeDisplay(); + void SetDragTimeDisplay(uint16_t dragTime); +}; +} // namespace OHOS +#endif // UI_TEST_EVENT_INJECTOR_H +#endif // ENABLE_DEBUG diff --git a/test/uitest/test_font/ui_test_font.cpp b/test/uitest/test_font/ui_test_font.cpp new file mode 100755 index 0000000..a40f53b --- /dev/null +++ b/test/uitest/test_font/ui_test_font.cpp @@ -0,0 +1,208 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "ui_test_font.h" +#include "common/screen.h" +#include "components/ui_checkbox.h" +#include "components/ui_label.h" +#include "font/ui_font.h" + +namespace OHOS { +namespace { +const int16_t GAP = 15; +const int16_t TITLE_HEIGHT = 20; +const uint16_t LABEL_WIDTH = 400; +const uint16_t LABEL_HEIGHT = 50; +const uint16_t BUF_SIZE = 200; +static uint8_t g_newFontPsramBaseAddr[OHOS::MIN_FONT_PSRAM_LENGTH]; +} // namespace + +void UITestFont::SetUp() +{ + if (container_ == nullptr) { + container_ = new UIScrollView(); + container_->SetThrowDrag(true); + container_->SetHorizontalScrollState(false); + container_->Resize(Screen::GetInstance().GetWidth(), Screen::GetInstance().GetHeight() - LABEL_HEIGHT); + positionX_ = 50; // 50: init position x + positionY_ = 5; // 5: init position y + } +} + +void UITestFont::TearDown() +{ + DeleteChildren(container_); + container_ = nullptr; +} + +void UITestFont::InnerTestTitle(const char* title) +{ + UILabel* titleLabel = new UILabel(); + titleLabel->SetPosition(TEXT_DISTANCE_TO_LEFT_SIDE, positionY_, Screen::GetInstance().GetWidth(), + TITLE_LABEL_DEFAULT_HEIGHT); + titleLabel->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); + titleLabel->SetText(title); + container_->Add(titleLabel); + positionY_ += TITLE_HEIGHT + GAP; +} + +UIView* UITestFont::GetTestView() +{ + Font_FontEngine_FontConvert_Test_FontTestSetFontId_001(); + Font_FontEngine_FontConvert_Test_FontTestSetFont_001(); + Font_FontEngine_FontConvert_Test_FontTestGetFontHeight_001(); + Font_FontEngine_FontConvert_Test_FontTestGetFontVersion_001(); + Font_FontEngine_FontConvert_Test_FontTestGetFontId_001(); + Font_FontEngine_FontConvert_Test_FontTestGetFontHeight_001(); + Font_FontEngine_FontConvert_Test_FontTestPsram_001(); + Font_FontEngine_FontConvert_Test_FontTestFontPath_001(); + return container_; +} + +void UITestFont::Font_FontEngine_FontConvert_Test_FontTestPsram_001() +{ + if (container_ != nullptr) { + InnerTestTitle("Test Psram"); + UIFont::GetInstance()->SetPsramMemory(reinterpret_cast(g_newFontPsramBaseAddr), + OHOS::MIN_FONT_PSRAM_LENGTH); + UILabel* label = new UILabel(); + label->SetPosition(positionX_, positionY_); + label->Resize(LABEL_WIDTH, LABEL_HEIGHT); + label->SetLineBreakMode(UILabel::LINE_BREAK_WRAP); + label->SetFont(DEFAULT_VECTOR_FONT_FILENAME, 18); // 18 : size + char buf[BUF_SIZE] = {0}; + label->SetText(reinterpret_cast(buf)); + container_->Add(label); + positionY_ += LABEL_HEIGHT + GAP; + } +} + +void UITestFont::Font_FontEngine_FontConvert_Test_FontTestFontPath_001() +{ + if (container_ != nullptr) { + InnerTestTitle("Test Font Path"); + std::string dpath; + std::string spath; + size_t len = dpath.size(); + size_t pos = dpath.find_last_of('\\'); + dpath.replace((pos + 1), (len - pos), "..\\..\\config\\font.bin"); + spath.replace((pos + 1), (len - pos), "..\\..\\config\\glyphs.bin"); + UILabel* label = new UILabel(); + label->SetPosition(positionX_, positionY_); + label->Resize(LABEL_WIDTH, LABEL_HEIGHT); + char buf[BUF_SIZE] = {0}; + label->SetFont(DEFAULT_VECTOR_FONT_FILENAME, 18); // 18 : size + label->SetText(reinterpret_cast(buf)); + container_->Add(label); + positionY_ += LABEL_HEIGHT + GAP; + } +} + +void UITestFont::Font_FontEngine_FontConvert_Test_FontTestSetFontId_001() +{ + if (container_ != nullptr) { + InnerTestTitle("Test Set Font Id"); + UILabel* label = new UILabel(); + label->SetPosition(positionX_, positionY_); + label->Resize(LABEL_WIDTH, LABEL_HEIGHT); + UIFont::GetInstance()->SetCurrentFontId(0); + label->SetFontId(0); + label->SetText("Hello!\nOHOS UIKIT!"); + label->SetLineBreakMode(UILabel::LINE_BREAK_WRAP); + container_->Add(label); + positionY_ += LABEL_HEIGHT + GAP; + } +} + +void UITestFont::Font_FontEngine_FontConvert_Test_FontTestSetFont_001() +{ + if (container_ != nullptr) { + InnerTestTitle("Test Set Font"); + UILabel* label = new UILabel(); + label->SetPosition(positionX_, positionY_); + label->Resize(LABEL_WIDTH, LABEL_HEIGHT); + uint8_t fontId = UIFont::GetInstance()->GetFontId("RobotoCondensed-Regular"); + UIFont::GetInstance()->SetCurrentFontId(fontId, 18); // 18: means font size + label->SetFont("RobotoCondensed-Regular", 18); // 18: means font size + label->SetText("Hello!\nOHOS UIKIT!"); + label->SetLineBreakMode(UILabel::LINE_BREAK_WRAP); + container_->Add(label); + positionY_ += LABEL_HEIGHT + GAP; + } +} + +void UITestFont::Font_FontEngine_FontConvert_Test_FontTestGetFontHeight_001() +{ + if (container_ != nullptr) { + InnerTestTitle("Test Get Font Height"); + UILabel* label = new UILabel(); + label->SetFont(DEFAULT_VECTOR_FONT_FILENAME, 18); // 18 : size + char buf[BUF_SIZE] = {0}; + label->SetText(reinterpret_cast(buf)); + label->SetPosition(positionX_, positionY_); + label->Resize(LABEL_WIDTH, LABEL_HEIGHT); + positionY_ += LABEL_HEIGHT + GAP; + container_->Add(label); + } +} + +void UITestFont::Font_FontEngine_FontConvert_Test_FontTestGetFontVersion_001() +{ + if (container_ != nullptr) { + InnerTestTitle("Test Get Font Version"); + UILabel* label = new UILabel(); + label->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); + char buf[BUF_SIZE] = {0}; + label->SetText(reinterpret_cast(buf)); + label->SetPosition(positionX_, positionY_); + label->Resize(LABEL_WIDTH, LABEL_HEIGHT); + positionY_ += LABEL_HEIGHT + GAP; + container_->Add(label); + } +} + +void UITestFont::Font_FontEngine_FontConvert_Test_FontTestGetFontId_001() +{ + if (container_ != nullptr) { + InnerTestTitle("Test Get Font Id"); + UILabel* label = new UILabel(); + label->SetFont("HYQiHei-65S", 18); // 18: means font size + UIFont::GetInstance()->GetFontId("HYQiHei-65S", 18); // 18: means font size + char buf[BUF_SIZE] = {0}; + label->SetText(reinterpret_cast(buf)); + label->SetPosition(positionX_, positionY_); + label->Resize(LABEL_WIDTH, LABEL_HEIGHT); + positionY_ += LABEL_HEIGHT + GAP; + container_->Add(label); + } +} + +void UITestFont::Font_FontEngine_FontConvert_Test_FontTestGetFontHeader_001() +{ + if (container_ != nullptr) { + InnerTestTitle("Test Get Font Header"); + UILabel* label = new UILabel(); + label->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); + FontHeader fontHeader; + UIFont::GetInstance()->GetCurrentFontHeader(fontHeader); + char buf[BUF_SIZE] = {0}; + label->SetText(reinterpret_cast(buf)); + label->SetPosition(positionX_, positionY_); + label->Resize(LABEL_WIDTH, LABEL_HEIGHT); + positionY_ += LABEL_HEIGHT + GAP; + container_->Add(label); + } +} +} // namespace OHOS \ No newline at end of file diff --git a/test/uitest/test_font/ui_test_font.h b/test/uitest/test_font/ui_test_font.h new file mode 100755 index 0000000..c4471da --- /dev/null +++ b/test/uitest/test_font/ui_test_font.h @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef UI_TEST_FONT_H +#define UI_TEST_FONT_H + +#include "components/ui_scroll_view.h" +#include "font/ui_font.h" +#include "ui_test.h" + +namespace OHOS { +class UITestFont : public UITest { +public: + UITestFont() {} + ~UITestFont() {} + void SetUp() override; + void TearDown() override; + UIView* GetTestView() override; + + /** + * @brief Test psram + */ + void Font_FontEngine_FontConvert_Test_FontTestPsram_001(); + + /** + * @brief Test Font path + */ + void Font_FontEngine_FontConvert_Test_FontTestFontPath_001(); + + /** + * @brief Test Set Font Id + */ + void Font_FontEngine_FontConvert_Test_FontTestSetFontId_001(); + + /** + * @brief Test Set Font + */ + void Font_FontEngine_FontConvert_Test_FontTestSetFont_001(); + + /** + * @brief Test Get Font Height + */ + void Font_FontEngine_FontConvert_Test_FontTestGetFontHeight_001(); + + /** + * @brief Test get font version + */ + void Font_FontEngine_FontConvert_Test_FontTestGetFontVersion_001(); + + /** + * @brief Test get font Id + */ + void Font_FontEngine_FontConvert_Test_FontTestGetFontId_001(); + + /** + * @brief Test get font header + */ + void Font_FontEngine_FontConvert_Test_FontTestGetFontHeader_001(); + +private: + UIScrollView* container_ = nullptr; + void InnerTestTitle(const char* title); +}; +} // namespace OHOS +#endif // UI_TEST_FONT_H diff --git a/test/uitest/test_image/ui_test_image.cpp b/test/uitest/test_image/ui_test_image.cpp new file mode 100755 index 0000000..fe21ed1 --- /dev/null +++ b/test/uitest/test_image/ui_test_image.cpp @@ -0,0 +1,518 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "ui_test_image.h" +#include "common/screen.h" +#include "components/ui_label.h" +#include "default_resource/check_box_res.h" +#ifdef VERSION_LITE +#include "components/ui_image_view.h" +#include "test_resource_config.h" +#endif +#include "imgdecode/image_load.h" + +namespace OHOS { +namespace { +int16_t g_height = 0; +} + +void UITestImage::SetUp() +{ + g_height = 0; + if (container_ == nullptr) { + container_ = new UIScrollView(); + container_->Resize(Screen::GetInstance().GetWidth(), Screen::GetInstance().GetHeight() - BACK_BUTTON_HEIGHT); + container_->SetHorizontalScrollState(false); + } +} + +void UITestImage::TearDown() +{ + DeleteChildren(container_); + container_ = nullptr; +#ifndef VERSION_LITE + gifImageView_ = nullptr; + gifToGif_ = nullptr; + gifToJpeg_ = nullptr; + gifToPng_ = nullptr; + gifToBin01_ = nullptr; + gifToBin02_ = nullptr; + gifToBin03_ = nullptr; + gifToBin04_ = nullptr; +#endif +} + +UIView* UITestImage::GetTestView() +{ + UIKit_UIImage_Test_SetImage_001(); + UIKit_UIImage_Test_SetImage_002(); + UIKit_UIImage_Test_SetImage_004(); + UIKit_UIImage_Test_SetImage_005(); + UIKit_UIImage_Test_SetImage_006(); + UIKit_UIImage_Test_SetImage_007(); + UIKit_UIImage_Test_SetImage_008(); + UIKit_UIImage_Test_SetImage_009(); + UIKit_UIImage_Test_SetImage_010(); + UIKit_UIImage_Test_SetImage_011(); + UIKit_UIImage_Test_SetImage_012(); + UIKit_UIImage_Test_SetImage_013(); + UIKit_UIImage_Test_SetImage_014(); +#ifndef VERSION_LITE + UIKit_UIImage_Test_SetImage_015(); + UIKit_UIImage_Test_SetImage_016(); +#endif + UIKit_UIImage_Test_Uncompress_001(); + return container_; +} + +const char* UITestImage::GetCharByImageSrcType(ImageSrcType srcType) const +{ + if (srcType == IMG_SRC_VARIABLE) { + return "the src of image is variable type"; + } else if (srcType == IMG_SRC_FILE) { + return "the src of image is file type"; + } else { + return "Null"; + } +} + +void UITestImage::UIKit_UIImage_Test_SetImage_001() +{ + if (container_ != nullptr) { + UILabel* label = new UILabel(); + container_->Add(label); + label->SetPosition(TEXT_DISTANCE_TO_LEFT_SIDE, g_height + 5, // 5: increase y-coordinate + Screen::GetInstance().GetWidth(), TITLE_LABEL_DEFAULT_HEIGHT); + label->SetText("rgb888 格式图片测试 "); + label->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); + + UIImageView* imageView = new UIImageView(); + imageView->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE, g_height + 40); // 40 : offset + imageView->SetWidth(50); // 50 : size + imageView->SetHeight(50); // 50 : size + imageView->SetSrc(BLUE_RGB888_IMAGE_PATH); + + UILabel* label2 = new UILabel(); + // 160 : offset 65 : offset 300 : offset + label2->SetPosition(160, g_height + 65, 300, TITLE_LABEL_DEFAULT_HEIGHT); + label2->SetText(GetCharByImageSrcType(imageView->GetSrcType())); + label2->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); + label2->SetStyle(STYLE_TEXT_COLOR, Color::Black().full); + label2->SetStyle(STYLE_BACKGROUND_COLOR, Color::Yellow().full); + label2->SetStyle(STYLE_BACKGROUND_OPA, OPA_OPAQUE); + + container_->Add(label2); + container_->Add(imageView); + g_height += 130; // offset=130 + } +} + +void UITestImage::UIKit_UIImage_Test_SetImage_002() +{ + if (container_ != nullptr) { + UILabel* label = new UILabel(); + container_->Add(label); + label->SetPosition(TEXT_DISTANCE_TO_LEFT_SIDE, g_height, Screen::GetInstance().GetWidth(), + TITLE_LABEL_DEFAULT_HEIGHT); + label->SetText("显示ARGB8888bin文件图片 "); + label->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); + + UIImageView* imageView = new UIImageView(); + imageView->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE, g_height + 30); // 30: increase offset + imageView->SetWidth(50); // 50 : size + imageView->SetHeight(50); // 50 : size + imageView->SetSrc(BLUE_ARGB8888_IMAGE_PATH); + + container_->Add(imageView); + g_height += 120; // offset=120 + } +} + +void UITestImage::UIKit_UIImage_Test_SetImage_004() +{ + if (container_ != nullptr) { + UILabel* label = new UILabel(); + container_->Add(label); + label->SetPosition(TEXT_DISTANCE_TO_LEFT_SIDE, g_height + 5, // 5: increase offset + Screen::GetInstance().GetWidth(), TITLE_LABEL_DEFAULT_HEIGHT); // 5: increase offset + label->SetText("显示RGB565bin文件图片 "); + label->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); + + UIImageView* imageView = new UIImageView(); + imageView->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE, g_height + 35); // 35 : offset + imageView->SetWidth(50); // 50 : size + imageView->SetHeight(50); // 50 : size + imageView->SetSrc(BLUE_RGB565_IMAGE_PATH); + imageView->GetHeight(); + + container_->Add(imageView); + g_height += 140; // offset=140 + } +} + +void UITestImage::UIKit_UIImage_Test_SetImage_005() +{ + if (container_ != nullptr) { + UILabel* label = new UILabel(); + container_->Add(label); + label->SetPosition(TEXT_DISTANCE_TO_LEFT_SIDE, g_height, Screen::GetInstance().GetWidth(), + TITLE_LABEL_DEFAULT_HEIGHT); + label->SetText("显示ARGB8888 数组型图片 "); + label->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); + + UIImageView* imageView = new UIImageView(); + imageView->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE, g_height + 40); // 40 : increase offset + imageView->SetWidth(50); // 50 : size + imageView->SetHeight(50); // 50 : size + imageView->SetSrc(GetCheckBoxOnInfo()); + imageView->GetHeight(); + + UIImageView* imageView2 = new UIImageView(); + imageView2->SetPosition(110, g_height + 40); // 110 : offset 40 : increase offset + imageView2->SetWidth(50); // 50 : size + imageView2->SetHeight(50); // 50 : size + imageView2->SetSrc(GetCheckBoxOffInfo()); + imageView2->GetHeight(); + + container_->Add(imageView); + container_->Add(imageView2); + g_height += 100; // offset=100 + } +} + +void UITestImage::UIKit_UIImage_Test_SetImage_006() +{ + if (container_ != nullptr) { + UILabel* label = new UILabel(); + container_->Add(label); + label->SetPosition(TEXT_DISTANCE_TO_LEFT_SIDE, g_height, Screen::GetInstance().GetWidth(), + TITLE_LABEL_DEFAULT_HEIGHT); + label->SetText("显示24位真彩色jpg图片 "); + label->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); + + UIImageView* imageView = new UIImageView(); + imageView->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE, g_height + 30); // 30 : offset + imageView->SetWidth(50); // 50 : size + imageView->SetHeight(50); // 50 : size + imageView->SetSrc(JPEG_IMAGE_PATH); + imageView->GetHeight(); + container_->Add(imageView); + g_height += 190; // offset=190 + } +} + +void UITestImage::UIKit_UIImage_Test_SetImage_007() +{ + if (container_ != nullptr) { + UILabel* label = new UILabel(); + container_->Add(label); + label->SetPosition(TEXT_DISTANCE_TO_LEFT_SIDE, g_height, Screen::GetInstance().GetWidth(), + TITLE_LABEL_DEFAULT_HEIGHT); + label->SetText("显示位深1索引png图片 "); + label->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); + + UIImageView* imageView = new UIImageView(); + imageView->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE, g_height + 30); // 30 : offset + imageView->SetWidth(50); // 50 : size + imageView->SetHeight(50); // 50 : size + imageView->SetSrc(PNG_1_PALETTE_IMAGE_PATH); + imageView->GetHeight(); + container_->Add(imageView); + g_height += 90; // offset=90 + } +} + +void UITestImage::UIKit_UIImage_Test_SetImage_008() +{ + if (container_ != nullptr) { + UILabel* label = new UILabel(); + container_->Add(label); + label->SetPosition(TEXT_DISTANCE_TO_LEFT_SIDE, g_height, Screen::GetInstance().GetWidth(), + TITLE_LABEL_DEFAULT_HEIGHT); + label->SetText("显示位深2索引png图片 "); + label->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); + + UIImageView* imageView = new UIImageView(); + imageView->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE, g_height + 30); // 30 : offset + imageView->SetWidth(50); // 50 : size + imageView->SetHeight(50); // 50 : size + imageView->SetSrc(PNG_2_PALETTE_IMAGE_PATH); + imageView->GetHeight(); + container_->Add(imageView); + g_height += 90; // offset=90 + } +} + +void UITestImage::UIKit_UIImage_Test_SetImage_009() +{ + if (container_ != nullptr) { + UILabel* label = new UILabel(); + container_->Add(label); + label->SetPosition(TEXT_DISTANCE_TO_LEFT_SIDE, g_height, Screen::GetInstance().GetWidth(), + TITLE_LABEL_DEFAULT_HEIGHT); + label->SetText("显示位深4索引png图片 "); + label->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); + + UIImageView* imageView = new UIImageView(); + imageView->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE, g_height + 30); // 30 : offset + imageView->SetWidth(50); // 50 : size + imageView->SetHeight(50); // 50 : size + imageView->SetSrc(PNG_4_PALETTE_IMAGE_PATH); + imageView->GetHeight(); + container_->Add(imageView); + g_height += 100; // offset=100 + } +} + +void UITestImage::UIKit_UIImage_Test_SetImage_010() +{ + if (container_ != nullptr) { + UILabel* label = new UILabel(); + container_->Add(label); + label->SetPosition(TEXT_DISTANCE_TO_LEFT_SIDE, g_height, Screen::GetInstance().GetWidth(), + TITLE_LABEL_DEFAULT_HEIGHT); + label->SetText("显示位深8索引png图片 "); + label->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); + + UIImageView* imageView = new UIImageView(); + imageView->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE, g_height + 30); // 30 : offset + imageView->SetWidth(50); // 50 : size + imageView->SetHeight(50); // 50 : size + imageView->SetSrc(PNG_8_PALETTE_IMAGE_PATH); + imageView->GetHeight(); + container_->Add(imageView); + g_height += 100; // offset=100 + } +} + +void UITestImage::UIKit_UIImage_Test_SetImage_011() +{ + if (container_ != nullptr) { + UILabel* label = new UILabel(); + container_->Add(label); + label->SetPosition(TEXT_DISTANCE_TO_LEFT_SIDE, g_height, Screen::GetInstance().GetWidth(), + TITLE_LABEL_DEFAULT_HEIGHT); + label->SetText("显示位深24真彩色png图片 "); + label->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); + + UIImageView* imageView = new UIImageView(); + imageView->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE, g_height + 30); // 30 : offset + imageView->SetWidth(50); // 50 : size + imageView->SetHeight(50); // 50 : size + imageView->SetSrc(PNG_24_RGB_IMAGE_PATH); + imageView->GetHeight(); + container_->Add(imageView); + g_height += 100; // offset=100 + } +} + +void UITestImage::UIKit_UIImage_Test_SetImage_012() +{ + if (container_ != nullptr) { + UILabel* label = new UILabel(); + container_->Add(label); + label->SetPosition(TEXT_DISTANCE_TO_LEFT_SIDE, g_height, Screen::GetInstance().GetWidth(), + TITLE_LABEL_DEFAULT_HEIGHT); + label->SetText("显示位深32真彩色带Alpha通道png图片 "); + label->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); + + UIImageView* imageView = new UIImageView(); + imageView->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE, g_height + 30); // 30 : offset + imageView->SetWidth(50); // 50 : size + imageView->SetHeight(50); // 50 : size + imageView->SetSrc(PNG_32_RGB_ALPHA_IMAGE_PATH); + imageView->GetHeight(); + container_->Add(imageView); + g_height += 100; // offset=100 + } +} + +void UITestImage::UIKit_UIImage_Test_SetImage_013() +{ + if (container_ != nullptr) { + UILabel* label = new UILabel(); + container_->Add(label); + label->SetPosition(TEXT_DISTANCE_TO_LEFT_SIDE, g_height, Screen::GetInstance().GetWidth(), + TITLE_LABEL_DEFAULT_HEIGHT); + label->SetText("显示位深8灰度png图片 "); + label->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); + + UIImageView* imageView = new UIImageView(); + imageView->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE, g_height + 30); // 30 : offset + imageView->SetWidth(50); // 50 : size + imageView->SetHeight(50); // 50 : size + imageView->SetSrc(PNG_8_GRAY_IMAGE_PATH); + imageView->GetHeight(); + container_->Add(imageView); + g_height += 100; // offset=100 + } +} + +void UITestImage::UIKit_UIImage_Test_SetImage_014() +{ + if (container_ != nullptr) { + UILabel* label = new UILabel(); + container_->Add(label); + label->SetPosition(TEXT_DISTANCE_TO_LEFT_SIDE, g_height, Screen::GetInstance().GetWidth(), + TITLE_LABEL_DEFAULT_HEIGHT); + label->SetText("显示位深16灰度png图片 "); + label->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); + + UIImageView* imageView = new UIImageView(); + imageView->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE, g_height + 30); // 30 : offset + imageView->SetWidth(50); // 50 : size + imageView->SetHeight(50); // 50 : size + imageView->SetSrc(PNG_16_GRAY_IMAGE_PATH); + imageView->GetHeight(); + container_->Add(imageView); + g_height += 100; // offset=100 + } +} + +#ifndef VERSION_LITE +void UITestImage::UIKit_UIImage_Test_SetImage_015() +{ + if (container_ != nullptr) { + UILabel* label = new UILabel(); + container_->Add(label); + label->SetPosition(TEXT_DISTANCE_TO_LEFT_SIDE, g_height, Screen::GetInstance().GetWidth(), + TITLE_LABEL_DEFAULT_HEIGHT); + label->SetText("显示gif文件图片 "); + label->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); + + UIImageView* imageView = new UIImageView(); + imageView->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE, g_height + 30); // 30: Y-coordinate + imageView->SetSrc(GIF_IMAGE_PATH1); + container_->Add(imageView); + + UIImageView* imageView2 = new UIImageView(); + imageView2->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE, g_height + 120); // 120: Y-coordinate + imageView2->SetSrc(GIF_IMAGE_PATH2); + container_->Add(imageView2); + g_height += 180; // offset=180 + } +} + +void UITestImage::UIKit_UIImage_Test_SetImage_016() +{ + if (container_ != nullptr) { + UILabel* label = new UILabel(); + container_->Add(label); + label->SetPosition(TEXT_DISTANCE_TO_LEFT_SIDE, g_height, Screen::GetInstance().GetWidth(), + TITLE_LABEL_DEFAULT_HEIGHT); + label->SetText("不同类型图片切换 "); + label->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); + gifImageView_ = new UIImageView(); + gifImageView_->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE, 1790); // 1790: Y-coordinate + gifImageView_->SetSrc(GIF_IMAGE_PATH1); + container_->Add(gifImageView_); + gifToGif_ = new UILabelButton(); + SetUpButton(gifToGif_, "切换GIF"); + uint16_t gifHeight = g_height + 30; // 30: offset + gifToGif_->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE, gifHeight); + gifToJpeg_ = new UILabelButton(); + SetUpButton(gifToJpeg_, "切换JPEG"); + gifToJpeg_->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE + 160, gifHeight); // 160: offset + gifToPng_ = new UILabelButton(); + SetUpButton(gifToPng_, "切换PNG"); + gifToPng_->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE + 320, gifHeight); // 320: offset + gifToBin01_ = new UILabelButton(); + SetUpButton(gifToBin01_, "切换rgb888"); + gifToBin01_->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE + 480, gifHeight); // 480: offset + gifToBin02_ = new UILabelButton(); + SetUpButton(gifToBin02_, "ARGB8888bin"); + gifHeight += 50; // 50: offset + gifToBin02_->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE, gifHeight); + gifToBin03_ = new UILabelButton(); + SetUpButton(gifToBin03_, "RGB565bin"); + gifToBin03_->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE + 160, gifHeight); // 160: offset + gifToBin04_ = new UILabelButton(); + SetUpButton(gifToBin04_, "ARGB8888数组"); + gifToBin04_->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE + 320, gifHeight); // 320: offset + g_height += 300; // offset=300 + } +} + +void UITestImage::SetUpButton(UILabelButton* btn, const char* title) +{ + if (btn == nullptr) { + return; + } + container_->Add(btn); + btn->Resize(BUTTON_WIDHT3, BUTTON_HEIGHT3); + btn->SetText(title); + btn->SetFont(DEFAULT_VECTOR_FONT_FILENAME, BUTTON_LABEL_SIZE); + btn->SetOnClickListener(this); + btn->SetStyleForState(STYLE_BORDER_RADIUS, BUTTON_STYLE_BORDER_RADIUS_VALUE, UIButton::RELEASED); + btn->SetStyleForState(STYLE_BORDER_RADIUS, BUTTON_STYLE_BORDER_RADIUS_VALUE, UIButton::PRESSED); + btn->SetStyleForState(STYLE_BORDER_RADIUS, BUTTON_STYLE_BORDER_RADIUS_VALUE, UIButton::INACTIVE); + btn->SetStyleForState(STYLE_BACKGROUND_COLOR, BUTTON_STYLE_BACKGROUND_COLOR_VALUE, UIButton::RELEASED); + btn->SetStyleForState(STYLE_BACKGROUND_COLOR, BUTTON_STYLE_BACKGROUND_COLOR_VALUE, UIButton::PRESSED); + btn->SetStyleForState(STYLE_BACKGROUND_COLOR, BUTTON_STYLE_BACKGROUND_COLOR_VALUE, UIButton::INACTIVE); +} + +bool UITestImage::OnClick(UIView &view, const ClickEvent& event) +{ + if (gifImageView_ == nullptr) { + return false; + } + if (&view == gifToGif_) { + gifImageView_->SetSrc(GIF_IMAGE_PATH2); + } else if (&view == gifToJpeg_) { + gifImageView_->SetSrc(JPEG_IMAGE_PATH); + } else if (&view == gifToPng_) { + gifImageView_->SetSrc(BLUE_IMAGE_PATH); + } else if (&view == gifToBin01_) { + gifImageView_->SetSrc(BLUE_RGB888_IMAGE_PATH); + } else if (&view == gifToBin02_) { + gifImageView_->SetSrc(BLUE_ARGB8888_IMAGE_PATH); + } else if (&view == gifToBin03_) { + gifImageView_->SetSrc(BLUE_RGB565_IMAGE_PATH); + } else if (&view == gifToBin04_) { + gifImageView_->SetSrc(GetCheckBoxOnInfo()); + } + return true; +} +#endif + +void UITestImage::UIKit_UIImage_Test_Uncompress_001() +{ + if (container_ != nullptr) { + UILabel* label = new UILabel(); + container_->Add(label); + label->SetPosition(TEXT_DISTANCE_TO_LEFT_SIDE, g_height, Screen::GetInstance().GetWidth(), + TITLE_LABEL_DEFAULT_HEIGHT); + label->SetText("图片解压测试"); + label->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); + + UIImageView* imageView1 = new UIImageView(); + imageView1->SetPosition(48, g_height + 30); // 48 : offset; 30 : offset + imageView1->SetSrc(IMAGE_DIR "blue_compress.bin"); + + UIImageView* imageView2 = new UIImageView(); + imageView2->SetPosition(158, g_height + 30); // 158 : offset 30 : offset + imageView2->SetSrc(IMAGE_DIR "red_compress.bin"); + + UIImageView* imageView3 = new UIImageView(); + imageView3->SetPosition(268, g_height + 30); // 268 : offset 30 : offset + imageView3->SetSrc(IMAGE_DIR "FaultInjection.bin"); + + container_->Add(imageView1); + container_->Add(imageView2); + container_->Add(imageView3); + g_height += 100; // offset=100 + } +} +} // namespace OHOS diff --git a/test/uitest/test_image/ui_test_image.h b/test/uitest/test_image/ui_test_image.h new file mode 100755 index 0000000..e99f106 --- /dev/null +++ b/test/uitest/test_image/ui_test_image.h @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef UI_TEST_IMAGE_H +#define UI_TEST_IMAGE_H + +#include "components/ui_scroll_view.h" +#include "imgdecode/cache_manager.h" +#include "ui_test.h" + +#ifndef VERSION_LITE +#include "components/ui_image_view.h" +#include "components/ui_label_button.h" +#include "test_resource_config.h" +#endif + +namespace OHOS { +#ifndef VERSION_LITE +class UITestImage : public UITest, public OHOS::UIView::OnClickListener { +#else +class UITestImage : public UITest { +#endif +public: + UITestImage() {} + ~UITestImage() {} + void SetUp() override; + void TearDown() override; + UIView* GetTestView() override; + void UIKit_UIImage_Test_SetImage_001(); + void UIKit_UIImage_Test_SetImage_002(); + void UIKit_UIImage_Test_SetImage_004(); + void UIKit_UIImage_Test_SetImage_005(); + void UIKit_UIImage_Test_SetImage_006(); + void UIKit_UIImage_Test_SetImage_007(); + void UIKit_UIImage_Test_SetImage_008(); + void UIKit_UIImage_Test_SetImage_009(); + void UIKit_UIImage_Test_SetImage_010(); + void UIKit_UIImage_Test_SetImage_011(); + void UIKit_UIImage_Test_SetImage_012(); + void UIKit_UIImage_Test_SetImage_013(); + void UIKit_UIImage_Test_SetImage_014(); +#ifndef VERSION_LITE + void UIKit_UIImage_Test_SetImage_015(); + void UIKit_UIImage_Test_SetImage_016(); +#endif + void UIKit_UIImage_Test_Uncompress_001(); + +private: + const char* GetCharByImageSrcType(ImageSrcType srcType) const; +#ifndef VERSION_LITE + bool OnClick(UIView &view, const ClickEvent& event) override; + void SetUpButton(UILabelButton* btn, const char* title); +#endif + UIScrollView* container_ = nullptr; +#ifndef VERSION_LITE + UIImageView* gifImageView_ = nullptr; + UILabelButton* gifToGif_ = nullptr; + UILabelButton* gifToJpeg_ = nullptr; + UILabelButton* gifToPng_ = nullptr; + UILabelButton* gifToBin01_ = nullptr; + UILabelButton* gifToBin02_ = nullptr; + UILabelButton* gifToBin03_ = nullptr; + UILabelButton* gifToBin04_ = nullptr; +#endif +}; +} // namespace OHOS +#endif // UI_TEST_IMAGE_H diff --git a/test/uitest/test_image_animator/ui_test_image_animator.cpp b/test/uitest/test_image_animator/ui_test_image_animator.cpp new file mode 100755 index 0000000..8ae85b3 --- /dev/null +++ b/test/uitest/test_image_animator/ui_test_image_animator.cpp @@ -0,0 +1,428 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "ui_test_image_animator.h" +#include "common/screen.h" +#include "test_resource_config.h" + +namespace OHOS { +namespace { +static ImageAnimatorInfo g_imageAnimatorInfo[4] = { + {IMAGE_ANIMATOR_0_PATH, {84, 108}, 116, 116, IMG_SRC_FILE_PATH}, + {IMAGE_ANIMATOR_1_PATH, {84, 108}, 116, 116, IMG_SRC_FILE_PATH}, + {IMAGE_ANIMATOR_2_PATH, {84, 108}, 116, 116, IMG_SRC_FILE_PATH}, + {IMAGE_ANIMATOR_3_PATH, {84, 108}, 116, 116, IMG_SRC_FILE_PATH}, +}; + +static ImageAnimatorInfo g_imageAnimatorInfo2[4] = { + {BLUE_IMAGE_PATH, {84, 108}, 94, 94, IMG_SRC_FILE_PATH}, + {RED_IMAGE_PATH, {84, 108}, 94, 94, IMG_SRC_FILE_PATH}, + {GREEN_IMAGE_PATH, {84, 108}, 94, 94, IMG_SRC_FILE_PATH}, + {YELLOW_IMAGE_PATH, {84, 108}, 94, 94, IMG_SRC_FILE_PATH}, +}; +} // namespace + +void UITestImageAnimator::SetUp() +{ + if (container_ == nullptr) { + container_ = new UIScrollView(); + container_->Resize(Screen::GetInstance().GetWidth(), Screen::GetInstance().GetHeight() - BACK_BUTTON_HEIGHT); + + UIViewGroup* uiViewGroup = new UIViewGroup(); + // 320: width; 390: height + uiViewGroup->SetPosition(0, 0, 320, 390); + container_->Add(uiViewGroup); + UILabel* label = new UILabel(); + uiViewGroup->Add(label); + // 288: width; 48: height + label->SetPosition(TEXT_DISTANCE_TO_LEFT_SIDE, TEXT_DISTANCE_TO_TOP_SIDE, 288, 48); + label->SetText("UIImageAnimator效果"); + label->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); + UIViewGroup* uiViewGroupFrame_ = new UIViewGroup(); + uiViewGroup->Add(uiViewGroupFrame_); + // 288: width; 336: height + uiViewGroupFrame_->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE2, VIEW_DISTANCE_TO_TOP_SIDE, 288, 336); + uiViewGroupFrame_->SetStyle(STYLE_BORDER_COLOR, Color::White().full); + uiViewGroupFrame_->SetStyle(STYLE_BORDER_OPA, HALF_OPA_OPAQUE); + uiViewGroupFrame_->SetStyle(STYLE_BORDER_WIDTH, VIEW_STYLE_BORDER_WIDTH); + uiViewGroupFrame_->SetStyle(STYLE_BORDER_RADIUS, VIEW_STYLE_BORDER_RADIUS); + uiViewGroupFrame_->SetStyle(STYLE_BACKGROUND_OPA, 0); + + imageAnimator_ = new UIImageAnimatorView(); + imageAnimator_->SetPosition(50, 50, 200, 200); // 50 : offset 50 : offset 200 : offset 200: offset + imageAnimator_->SetImageAnimatorSrc(g_imageAnimatorInfo, 4, 100); // 4: the number of images, 100: updating time + imageAnimator_->Start(); + listener_ = new TestAnimatorStopListener(container_); + listener_->Init(); + uiViewGroupFrame_->Add(imageAnimator_); + imageAnimator_->LayoutCenterOfParent(); + } + + if (layout_ == nullptr) { + layout_ = new GridLayout(); + uint16_t height = Screen::GetInstance().GetHeight(); + layout_->SetPosition(370, 0, 320, height - 50); // 370: x , 320: width, 50: offset + container_->Add(layout_); + layout_->SetLayoutDirection(LAYOUT_VER); + layout_->SetRows(9); // 9 : rows + layout_->SetCols(2); // 2 : columns + } + + InitImageInfo(); +} + +void UITestImageAnimator::InitImageInfo() +{ + const uint16_t pixelByteSize = 4; // 4: bytes per pixel + const uint16_t width = 100; // 100: image's width + const uint16_t height = 100; // 100: image's height + uint32_t dataSize = width * height * pixelByteSize; + uint8_t* srcData1 = static_cast(UIMalloc(dataSize)); + if (srcData1 == nullptr) { + return; + } + + for (uint32_t i = 0; i < dataSize; i += pixelByteSize) { + srcData1[i] = 255; // 255: pixel value + srcData1[i + 1] = 0; // 1: set green channel + srcData1[i + 2] = 0; // 2: set red channel + srcData1[i + 3] = OPA_OPAQUE; // 3: set alpha channel + } + imageInfo1_ = static_cast(UIMalloc(sizeof(ImageInfo))); + if (imageInfo1_ == nullptr) { + UIFree(srcData1); + return; + } + + imageInfo1_->header.width = width; + imageInfo1_->header.height = height; + imageInfo1_->header.colorMode = ColorMode::ARGB8888; + imageInfo1_->dataSize = dataSize; + imageInfo1_->data = srcData1; + + uint8_t* srcData2 = static_cast(UIMalloc(dataSize)); + if (srcData2 == nullptr) { + UIFree(imageInfo1_); + UIFree(srcData1); + return; + } + for (uint32_t i = 0; i < dataSize; i += pixelByteSize) { + srcData2[i] = 0; // set blue channel + srcData2[i + 1] = 255; // 1: set green channel 255: pixel value + srcData2[i + 2] = 0; // 2: set red channel + srcData2[i + 3] = OPA_OPAQUE; // 3: set alpha channel + } + + imageInfo2_ = static_cast(UIMalloc(sizeof(ImageInfo))); + if (imageInfo2_ == nullptr) { + UIFree(srcData2); + UIFree(imageInfo1_); + UIFree(srcData1); + return; + } + imageInfo2_->header.width = width; + imageInfo2_->header.height = height; + imageInfo2_->header.colorMode = ARGB8888; + imageInfo2_->dataSize = dataSize; + imageInfo2_->data = srcData2; + + uint8_t* srcData3 = static_cast(UIMalloc(dataSize)); + if (srcData3 == nullptr) { + UIFree(imageInfo2_); + UIFree(srcData2); + UIFree(imageInfo1_); + UIFree(srcData1); + return; + } + for (uint32_t i = 0; i < dataSize; i += pixelByteSize) { + srcData3[i] = 0; // set blue channel + srcData3[i + 1] = 0; // 1: set green channel + srcData3[i + 2] = 255; // 2: set red channel 255: pixel value + srcData3[i + 3] = OPA_OPAQUE; // 3: set alpha channel + } + + imageInfo3_ = static_cast(UIMalloc(sizeof(ImageInfo))); + if (imageInfo3_ == nullptr) { + UIFree(srcData3); + UIFree(imageInfo2_); + UIFree(srcData2); + UIFree(imageInfo1_); + UIFree(srcData1); + return; + } + imageInfo3_->header.width = width; + imageInfo3_->header.height = height; + imageInfo3_->header.colorMode = ARGB8888; + imageInfo3_->dataSize = dataSize; + imageInfo3_->data = srcData3; + + imageAnimatorImageInfo_[0].imageInfo = imageInfo1_; + imageAnimatorImageInfo_[0].pos = {84, 108}; + imageAnimatorImageInfo_[0].width = 100; // 100: width value + imageAnimatorImageInfo_[0].height = 100; // 100: height value + imageAnimatorImageInfo_[0].imageType = IMG_SRC_IMAGE_INFO; + + imageAnimatorImageInfo_[1].imageInfo = imageInfo2_; + imageAnimatorImageInfo_[1].pos = {84, 108}; + imageAnimatorImageInfo_[1].width = 100; // 100: width value + imageAnimatorImageInfo_[1].height = 100; // 100: height value + imageAnimatorImageInfo_[1].imageType = IMG_SRC_IMAGE_INFO; + + imageAnimatorImageInfo_[2].imageInfo = imageInfo3_; // 2: image index + imageAnimatorImageInfo_[2].pos = {84, 108}; // 2: image index + imageAnimatorImageInfo_[2].width = 100; // 2: image index, 100: width value + imageAnimatorImageInfo_[2].height = 100; // 2: image index, 100: height value + imageAnimatorImageInfo_[2].imageType = IMG_SRC_IMAGE_INFO; // 2: image index +} + +void UITestImageAnimator::TearDown() +{ + DeleteChildren(container_); + container_ = nullptr; + imageAnimator_ = nullptr; + layout_ = nullptr; + delete listener_; + listener_ = nullptr; + + UIFree(reinterpret_cast(const_cast(imageInfo1_->data))); + imageInfo1_->data = nullptr; + UIFree(reinterpret_cast(const_cast(imageInfo2_->data))); + imageInfo2_->data = nullptr; + UIFree(reinterpret_cast(const_cast(imageInfo3_->data))); + imageInfo3_->data = nullptr; + UIFree(reinterpret_cast(const_cast(imageInfo1_))); + imageInfo1_ = nullptr; + UIFree(reinterpret_cast(const_cast(imageInfo2_))); + imageInfo2_ = nullptr; + UIFree(reinterpret_cast(const_cast(imageInfo3_))); + imageInfo3_ = nullptr; +} + +UIView* UITestImageAnimator::GetTestView() +{ + UIKit_ImageAnimator_Test_Start_001(); + UIKit_ImageAnimator_Test_Stop_002(); + UIKit_ImageAnimator_Test_Pause_003(); + UIKit_ImageAnimator_Test_Resume_004(); + UIKit_ImageAnimator_Test_SetImageAnimatorSrc_005(); + UIKit_ImageAnimator_Test_SetTickOfUpdate_006(); + UIKit_ImageAnimator_Test_SetSizeFixed_007(); + UIKit_ImageAnimator_Test_SetRepeat_008(); + UIKit_ImageAnimator_Test_SetReverse_009(); + UIKit_ImageAnimator_Test_SetAnimatorStopListener_010(); + UIKit_ImageAnimator_Test_SetRepeatTimes_011(); + UIKit_ImageAnimator_Test_SetFillMode_True_Forward_012(); + UIKit_ImageAnimator_Test_SetFillMode_True_Backward_013(); + UIKit_ImageAnimator_Test_SetFillMode_False_Forward_014(); + UIKit_ImageAnimator_Test_SetFillMode_False_Backward_015(); + UIKit_ImageAnimator_Test_SetImageInfo_016(); + + layout_->LayoutChildren(); + return container_; +} + +void UITestImageAnimator::SetUpButton(UILabelButton* btn, const char* title) +{ + if (btn == nullptr) { + return; + } + layout_->Add(btn); + btn->Resize(BUTTON_WIDHT2, BUTTON_HEIGHT2); + btn->SetText(title); + btn->SetFont(DEFAULT_VECTOR_FONT_FILENAME, BUTTON_LABEL_SIZE); + btn->SetOnClickListener(this); + btn->SetStyleForState(STYLE_BORDER_RADIUS, BUTTON_STYLE_BORDER_RADIUS_VALUE, UIButton::RELEASED); + btn->SetStyleForState(STYLE_BORDER_RADIUS, BUTTON_STYLE_BORDER_RADIUS_VALUE, UIButton::PRESSED); + btn->SetStyleForState(STYLE_BORDER_RADIUS, BUTTON_STYLE_BORDER_RADIUS_VALUE, UIButton::INACTIVE); + btn->SetStyleForState(STYLE_BACKGROUND_COLOR, BUTTON_STYLE_BACKGROUND_COLOR_VALUE, UIButton::RELEASED); + btn->SetStyleForState(STYLE_BACKGROUND_COLOR, BUTTON_STYLE_BACKGROUND_COLOR_VALUE, UIButton::PRESSED); + btn->SetStyleForState(STYLE_BACKGROUND_COLOR, BUTTON_STYLE_BACKGROUND_COLOR_VALUE, UIButton::INACTIVE); +} + +void UITestImageAnimator::UIKit_ImageAnimator_Test_Start_001() +{ + startBtn_ = new UILabelButton(); + SetUpButton(startBtn_, "Start"); +} + +void UITestImageAnimator::UIKit_ImageAnimator_Test_Stop_002() +{ + stopBtn_ = new UILabelButton(); + SetUpButton(stopBtn_, "Stop"); +} + +void UITestImageAnimator::UIKit_ImageAnimator_Test_Pause_003() +{ + pauseBtn_ = new UILabelButton(); + SetUpButton(pauseBtn_, "Pause"); +} + +void UITestImageAnimator::UIKit_ImageAnimator_Test_Resume_004() +{ + resumeBtn_ = new UILabelButton(); + SetUpButton(resumeBtn_, "Resume"); +} + +void UITestImageAnimator::UIKit_ImageAnimator_Test_SetImageAnimatorSrc_005() +{ + setImageBtn_ = new UILabelButton(); + SetUpButton(setImageBtn_, "设置图片"); +} + +void UITestImageAnimator::UIKit_ImageAnimator_Test_SetTickOfUpdate_006() +{ + setSpeedBtn_ = new UILabelButton(); + SetUpButton(setSpeedBtn_, "设置速度"); +} + +void UITestImageAnimator::UIKit_ImageAnimator_Test_SetSizeFixed_007() +{ + fixedBtn_ = new UILabelButton(); + SetUpButton(fixedBtn_, "图片大小固定"); +} + +void UITestImageAnimator::UIKit_ImageAnimator_Test_SetRepeat_008() +{ + repeatBtn_ = new UILabelButton(); + noRepeatBtn_ = new UILabelButton(); + SetUpButton(repeatBtn_, "循环播放"); + SetUpButton(noRepeatBtn_, "播放一次 "); +} + +void UITestImageAnimator::UIKit_ImageAnimator_Test_SetReverse_009() +{ + reverseOrderBtn_ = new UILabelButton(); + positiveOrderBtn_ = new UILabelButton(); + SetUpButton(reverseOrderBtn_, "逆序播放"); + SetUpButton(positiveOrderBtn_, "正序播放"); +} + +void UITestImageAnimator::UIKit_ImageAnimator_Test_SetAnimatorStopListener_010() +{ + listenerBtn_ = new UILabelButton(); + SetUpButton(listenerBtn_, "播放结束监听"); +} + +void UITestImageAnimator::UIKit_ImageAnimator_Test_SetRepeatTimes_011() +{ + repeatTimesBtn_ = new UILabelButton(); + SetUpButton(repeatTimesBtn_, "播放次数+"); +} + +void UITestImageAnimator::UIKit_ImageAnimator_Test_SetFillMode_True_Forward_012() +{ + fillModeTrueForwardBtn_ = new UILabelButton(); + SetUpButton(fillModeTrueForwardBtn_, "fillMode true 正播"); +} + +void UITestImageAnimator::UIKit_ImageAnimator_Test_SetFillMode_True_Backward_013() +{ + fillModeTrueBackwardBtn_ = new UILabelButton(); + SetUpButton(fillModeTrueBackwardBtn_, "fillMode true 逆播"); +} + +void UITestImageAnimator::UIKit_ImageAnimator_Test_SetFillMode_False_Forward_014() +{ + fillModeFalseForwardBtn_ = new UILabelButton(); + SetUpButton(fillModeFalseForwardBtn_, "fillMode false 正播"); +} + +void UITestImageAnimator::UIKit_ImageAnimator_Test_SetFillMode_False_Backward_015() +{ + fillModeFalseBackwardBtn_ = new UILabelButton(); + SetUpButton(fillModeFalseBackwardBtn_, "fillMode false 逆播"); +} + +void UITestImageAnimator::UIKit_ImageAnimator_Test_SetImageInfo_016() +{ + setImageInfoBtn_ = new UILabelButton(); + SetUpButton(setImageInfoBtn_, "设置ImageInfo"); +} + +bool UITestImageAnimator::OnClick(UIView& view, const ClickEvent& event) +{ + if (&view == startBtn_) { + imageAnimator_->Start(); + } else if (&view == stopBtn_) { + imageAnimator_->Stop(); + } else if (&view == pauseBtn_) { + imageAnimator_->Pause(); + } else if (&view == resumeBtn_) { + imageAnimator_->Resume(); + } else if (&view == setImageBtn_) { + imageAnimator_->Stop(); + imageAnimator_->SetImageAnimatorSrc(g_imageAnimatorInfo2, 4); // 4: the number of images + imageAnimator_->Start(); + } else if (&view == setSpeedBtn_) { + imageAnimator_->Stop(); + imageAnimator_->SetTimeOfUpdate(10); // 10: set time of update + imageAnimator_->Start(); + } else if (&view == fixedBtn_) { + imageAnimator_->SetSizeFixed(true); + imageAnimator_->SetPosition(50, 50, 200, 200); // 50 : offset 50 : offset 200 : offset 200 :offset + } else if (&view == repeatBtn_) { + imageAnimator_->Stop(); + imageAnimator_->SetRepeat(true); + imageAnimator_->Start(); + } else if (&view == noRepeatBtn_) { + imageAnimator_->Stop(); + imageAnimator_->SetRepeat(false); + imageAnimator_->Start(); + } else if (&view == reverseOrderBtn_) { + imageAnimator_->Stop(); + imageAnimator_->SetReverse(true); + imageAnimator_->Start(); + } else if (&view == positiveOrderBtn_) { + imageAnimator_->Stop(); + imageAnimator_->SetReverse(false); + imageAnimator_->Start(); + } else if (&view == listenerBtn_) { + imageAnimator_->SetAnimatorStopListener(listener_); + } else if (&view == repeatTimesBtn_) { + imageAnimator_->Stop(); + imageAnimator_->SetRepeatTimes(imageAnimator_->GetRepeatTimes() + 1); + imageAnimator_->Start(); + } else if (&view == fillModeTrueForwardBtn_) { + imageAnimator_->Stop(); + imageAnimator_->SetFillMode(true); + imageAnimator_->SetRepeat(false); + imageAnimator_->SetReverse(false); + imageAnimator_->Start(); + } else if (&view == fillModeTrueBackwardBtn_) { + imageAnimator_->Stop(); + imageAnimator_->SetFillMode(true); + imageAnimator_->SetRepeat(false); + imageAnimator_->SetReverse(true); + imageAnimator_->Start(); + } else if (&view == fillModeFalseForwardBtn_) { + imageAnimator_->Stop(); + imageAnimator_->SetFillMode(false); + imageAnimator_->SetRepeat(false); + imageAnimator_->SetReverse(false); + imageAnimator_->Start(); + } else if (&view == fillModeFalseBackwardBtn_) { + imageAnimator_->Stop(); + imageAnimator_->SetFillMode(false); + imageAnimator_->SetRepeat(false); + imageAnimator_->SetReverse(true); + imageAnimator_->Start(); + } else if (&view == setImageInfoBtn_) { + imageAnimator_->Stop(); + imageAnimator_->SetImageAnimatorSrc(imageAnimatorImageInfo_, 3); // 3: the number of images + imageAnimator_->Start(); + } + return true; +} +} // namespace OHOS diff --git a/test/uitest/test_image_animator/ui_test_image_animator.h b/test/uitest/test_image_animator/ui_test_image_animator.h new file mode 100755 index 0000000..75854d1 --- /dev/null +++ b/test/uitest/test_image_animator/ui_test_image_animator.h @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef UI_TEST_IMAGE_ANIMATOR_H +#define UI_TEST_IMAGE_ANIMATOR_H + +#include "components/ui_image_animator.h" +#include "components/ui_label.h" +#include "components/ui_label_button.h" +#include "components/ui_scroll_view.h" +#include "layout/grid_layout.h" +#include "ui_test.h" + +namespace OHOS { +class TestAnimatorStopListener : public UIImageAnimatorView::AnimatorStopListener { +public: + explicit TestAnimatorStopListener(UIViewGroup* viewGroup) : viewGroup_(viewGroup) + { + viewGroup_ = viewGroup; + } + ~TestAnimatorStopListener() {} + + void Init() + { + label_ = new UILabel(); + viewGroup_->Add(label_); + label_->SetPosition(24, 50, 200, 29); // 24: position x 50: position y 200: width 29: height + label_->SetText("OnAnimatorStop"); + label_->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); + label_->SetStyle(STYLE_TEXT_COLOR, Color::Black().full); + label_->SetStyle(STYLE_BACKGROUND_COLOR, Color::White().full); + label_->SetStyle(STYLE_BACKGROUND_OPA, 255); // 255: value + label_->SetVisible(false); + } + + void OnAnimatorStop(UIView& view) override + { + label_->SetVisible(true); + label_->Invalidate(); + } +private: + UILabel* label_ = nullptr; + UIViewGroup* viewGroup_ = nullptr; +}; + +class UITestImageAnimator : public UITest, public UIView::OnClickListener { +public: + UITestImageAnimator() {} + ~UITestImageAnimator() {} + void SetUp() override; + void TearDown() override; + UIView* GetTestView() override; + + void SetUpButton(UILabelButton* btn, const char* title); + + bool OnClick(UIView& view, const ClickEvent& event) override; + + void UIKit_ImageAnimator_Test_Start_001(); + void UIKit_ImageAnimator_Test_Stop_002(); + void UIKit_ImageAnimator_Test_Pause_003(); + void UIKit_ImageAnimator_Test_Resume_004(); + void UIKit_ImageAnimator_Test_SetImageAnimatorSrc_005(); + void UIKit_ImageAnimator_Test_SetTickOfUpdate_006(); + void UIKit_ImageAnimator_Test_SetSizeFixed_007(); + void UIKit_ImageAnimator_Test_SetRepeat_008(); + void UIKit_ImageAnimator_Test_SetReverse_009(); + void UIKit_ImageAnimator_Test_SetAnimatorStopListener_010(); + void UIKit_ImageAnimator_Test_SetRepeatTimes_011(); + void UIKit_ImageAnimator_Test_SetFillMode_True_Forward_012(); + void UIKit_ImageAnimator_Test_SetFillMode_True_Backward_013(); + void UIKit_ImageAnimator_Test_SetFillMode_False_Forward_014(); + void UIKit_ImageAnimator_Test_SetFillMode_False_Backward_015(); + void UIKit_ImageAnimator_Test_SetImageInfo_016(); + +private: + void InitImageInfo(); + UIScrollView* container_ = nullptr; + GridLayout* layout_ = nullptr; + UIImageAnimatorView* imageAnimator_ = nullptr; + TestAnimatorStopListener* listener_ = nullptr; + + UILabelButton* startBtn_ = nullptr; + UILabelButton* stopBtn_ = nullptr; + UILabelButton* pauseBtn_ = nullptr; + UILabelButton* resumeBtn_ = nullptr; + UILabelButton* setImageBtn_ = nullptr; + UILabelButton* setSpeedBtn_ = nullptr; + UILabelButton* fixedBtn_ = nullptr; + UILabelButton* repeatBtn_ = nullptr; + UILabelButton* noRepeatBtn_ = nullptr; + UILabelButton* reverseOrderBtn_ = nullptr; + UILabelButton* positiveOrderBtn_ = nullptr; + UILabelButton* listenerBtn_ = nullptr; + UILabelButton* repeatTimesBtn_ = nullptr; + UILabelButton* fillModeTrueForwardBtn_ = nullptr; + UILabelButton* fillModeTrueBackwardBtn_ = nullptr; + UILabelButton* fillModeFalseForwardBtn_ = nullptr; + UILabelButton* fillModeFalseBackwardBtn_ = nullptr; + UILabelButton* setImageInfoBtn_ = nullptr; + + ImageInfo* imageInfo1_ = nullptr; + ImageInfo* imageInfo2_ = nullptr; + ImageInfo* imageInfo3_ = nullptr; + ImageAnimatorInfo imageAnimatorImageInfo_[3] = { 0 }; +}; +} // namespace OHOS +#endif // UI_TEST_IMAGE_ANIMATOR_H diff --git a/test/uitest/test_input_event/ui_test_input_event.cpp b/test/uitest/test_input_event/ui_test_input_event.cpp new file mode 100755 index 0000000..a4c453f --- /dev/null +++ b/test/uitest/test_input_event/ui_test_input_event.cpp @@ -0,0 +1,617 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "ui_test_input_event.h" +#include "common/screen.h" +#include "components/root_view.h" + +namespace OHOS { +namespace { +const int16_t ITEM_H = 50; +const int16_t TEXT_H = 29; +const int16_t TEXT_W = 250; +const int16_t TEST_VIEW_H = 40; +const int16_t TEST_VIEW_W = 40; +const int16_t GAP = 5; +const int16_t TEST_VIEW_GAP = 80; +} // namespace + +class TestView : public UIView { +public: + TestView() {} + virtual ~TestView() {} + bool OnLongPressEvent(const LongPressEvent& event) override + { + if (label_ != nullptr) { + label_->SetText("long press!"); + label_->Invalidate(); + } + return UIView::OnLongPressEvent(event); + } + + bool OnDragEvent(const DragEvent& event) override + { + if (label_ != nullptr) { + label_->SetText("drag!"); + label_->Invalidate(); + } + return UIView::OnDragEvent(event); + } + + void SetSentence(const char* sentence) + { + sentence_ = sentence; + } + + bool OnClickEvent(const ClickEvent& event) override + { + if (label_ != nullptr) { + label_->SetText(sentence_); + label_->Invalidate(); + } + return UIView::OnClickEvent(event); + } + + bool OnPressEvent(const PressEvent& event) override + { + if (label_ != nullptr) { + label_->SetText("press!"); + label_->Invalidate(); + } + return UIView::OnPressEvent(event); + } + + bool OnReleaseEvent(const ReleaseEvent& event) override + { + if (label_ != nullptr) { + label_->SetText("release!"); + label_->Invalidate(); + } + return UIView::OnReleaseEvent(event); + } + + bool OnCancelEvent(const CancelEvent& event) override + { + if (label_ != nullptr) { + label_->SetText("cancel!"); + label_->Invalidate(); + } + return UIView::OnCancelEvent(event); + } + + void SetLabel(UILabel* label) + { + label_ = label; + } + + void SetLabel2(UILabel* label) + { + label2_ = label; + } + +private: + UILabel* label_ = nullptr; + UILabel* label2_ = nullptr; + const char* sentence_ = "click"; +}; + +class TestUIScrollView : public UIScrollView { +public: + TestUIScrollView() {} + virtual ~TestUIScrollView() {} + bool OnLongPressEvent(const LongPressEvent& event) override + { + if (label_ != nullptr) { + label_->SetText("long press!"); + label_->Invalidate(); + } + return UIView::OnLongPressEvent(event); + } + + bool OnDragEvent(const DragEvent& event) override + { + if (label_ != nullptr) { + label_->SetText("drag!"); + label_->Invalidate(); + } + return UIScrollView::OnDragEvent(event); + } + + bool OnDragStartEvent(const DragEvent& event) override + { + if (label_ != nullptr) { + label_->SetText("drag start!"); + label_->Invalidate(); + } + return UIScrollView::OnDragStartEvent(event); + } + + bool OnDragEndEvent(const DragEvent& event) override + { + if (label_ != nullptr) { + label_->SetText("drag end!"); + label_->Invalidate(); + } + return UIScrollView::OnDragEndEvent(event); + } + + void SetSentence(const char* sentence) + { + sentence_ = sentence; + } + + bool OnClickEvent(const ClickEvent& event) override + { + if (label_ != nullptr) { + label_->SetText(sentence_); + label_->Invalidate(); + } + return UIView::OnClickEvent(event); + } + + bool OnPressEvent(const PressEvent& event) override + { + if (label_ != nullptr) { + label_->SetText("press!"); + label_->Invalidate(); + } + return UIView::OnPressEvent(event); + } + + bool OnReleaseEvent(const ReleaseEvent& event) override + { + if (label_ != nullptr) { + label_->SetText("release!"); + label_->Invalidate(); + } + return UIView::OnReleaseEvent(event); + } + + bool OnCancelEvent(const CancelEvent& event) override + { + if (label_ != nullptr) { + label_->SetText("cancel!"); + label_->Invalidate(); + } + return UIView::OnCancelEvent(event); + } + + void SetLabel(UILabel* label) + { + label_ = label; + } + +private: + UILabel* label_ = nullptr; + const char* sentence_ = "click"; +}; + +void UITestInputEvent::SetUp() +{ + if (container_ == nullptr) { + container_ = new UIScrollView(); + container_->Resize(Screen::GetInstance().GetWidth(), Screen::GetInstance().GetHeight() - BACK_BUTTON_HEIGHT); + container_->SetHorizontalScrollState(false); + } + positionX_ = 48; // 48: position x + positionY_ = 0; +} + +void DeleteChildrenAndListener(UIView* view) +{ + if (view == nullptr) { + return; + } + while (view != nullptr) { + UIView* tempView = view; + view = view->GetNextSibling(); + if (tempView->IsViewGroup()) { + DeleteChildrenAndListener(static_cast(tempView)->GetChildrenHead()); + } + if (tempView->GetParent()) { + static_cast(tempView->GetParent())->Remove(tempView); + } + + if (tempView->GetOnClickListener()) { + delete tempView->GetOnClickListener(); + } + if (tempView->GetOnDragListener()) { + delete tempView->GetOnDragListener(); + } + if (tempView->GetOnLongPressListener()) { + delete tempView->GetOnLongPressListener(); + } + if (tempView->GetTouchListener()) { + delete tempView->GetTouchListener(); + } + + delete tempView; + } +} + +void UITestInputEvent::TearDown() +{ + DeleteChildrenAndListener(container_); + container_ = nullptr; + if (keyListener_ != nullptr) { + delete keyListener_; + keyListener_ = nullptr; + } +} + +UIView* UITestInputEvent::GetTestView() +{ + UIKit_Pointer_Input_Test_Dispatch_Simple_Event_001(); + UIKit_Pointer_Input_Test_Dispatch_Simple_Event_002(); + UIKit_Pointer_Input_Test_Dispatch_Drag_Event_001(); + UIKit_Pointer_Input_Test_Dispatch_Drag_Event_002(); + UIKit_Pointer_Input_Test_Dispatch_Drag_Event_003(); + UIKit_Pointer_Input_Test_Dispatch_Key_Event_001(); + UIKit_Pointer_Input_Test_Dispatch_InVisible_Event_001(); + UIKit_Pointer_Input_Test_Dispatch_Bubble_001(); + UIKit_Pointer_Input_Test_Dispatch_Bubble_002(); + UIKit_Pointer_Input_Test_Dispatch_Bubble_003(); + UIKit_Pointer_Input_Test_Dispatch_Bubble_004(); + UIKit_Pointer_Input_Test_Dispatch_Bubble_005(); + UIKit_Pointer_Input_Test_Dispatch_Bubble_006(); + UIKit_Pointer_Input_Test_Dispatch_Bubble_007(); + UIKit_Pointer_Input_Test_Dispatch_Bubble_008(); + UIKit_Pointer_Input_Test_Dispatch_Bubble_009(); + UIKit_Pointer_Input_Test_Dispatch_Bubble_010(); + return container_; +} + +void UITestInputEvent::UIKit_Pointer_Input_Test_Dispatch_Simple_Event_001() +{ + InnerTest("可点击对象事件测试 ", true, false, false); +} + +void UITestInputEvent::UIKit_Pointer_Input_Test_Dispatch_Simple_Event_002() +{ + InnerTest("不可点击对象事件测试 ", false, false, false); +} + +void UITestInputEvent::UIKit_Pointer_Input_Test_Dispatch_Drag_Event_001() +{ + InnerTest("可点击可拖拽dragparent测试 ", true, true, true); +} + +void UITestInputEvent::UIKit_Pointer_Input_Test_Dispatch_Drag_Event_002() +{ + InnerTest("可点击可拖拽非dragparent测试 ", true, true, false); +} + +void UITestInputEvent::UIKit_Pointer_Input_Test_Dispatch_Drag_Event_003() +{ + InnerTest("不可点击可拖拽测试 ", false, true, false); +} + +void UITestInputEvent::UIKit_Pointer_Input_Test_Dispatch_Bubble_001() +{ + positionY_ = 0; + InnerBubbleTest("可点击有监听事件不消费冒泡测试 ", true, true, true, false); +} + +void UITestInputEvent::UIKit_Pointer_Input_Test_Dispatch_Bubble_002() +{ + InnerBubbleTest("可点击有监听事件消费冒泡测试 ", true, true, true, true); +} + +void UITestInputEvent::UIKit_Pointer_Input_Test_Dispatch_Bubble_003() +{ + InnerBubbleTest("可点击无监听事件不消费冒泡测试 ", true, true, false, false); +} + +void UITestInputEvent::UIKit_Pointer_Input_Test_Dispatch_Bubble_004() +{ + InnerBubbleTest("不可点击有监听事件消费冒泡测试 ", false, false, true, true); +} + +void UITestInputEvent::UIKit_Pointer_Input_Test_Dispatch_Bubble_005() +{ + InnerBubbleDragTest("子父可拖拽有监听事件不消费冒泡测试 ", true, true, true, false); +} + +void UITestInputEvent::UIKit_Pointer_Input_Test_Dispatch_Bubble_006() +{ + InnerBubbleDragTest("子父可拖拽有监听事件消费冒泡测试 ", true, true, true, true); +} + +void UITestInputEvent::UIKit_Pointer_Input_Test_Dispatch_Bubble_007() +{ + InnerBubbleDragTest("子父可拖拽无监听事件消费冒泡测试 ", true, true, false, true); +} + +void UITestInputEvent::UIKit_Pointer_Input_Test_Dispatch_Bubble_008() +{ + InnerBubbleDragTest("子父不可拖拽有监听事件消费冒泡测试 ", false, false, true, true); +} + +void UITestInputEvent::UIKit_Pointer_Input_Test_Dispatch_Bubble_009() +{ + InnerBubbleDragTest("子不可拖拽父可拖拽有监听事件消费冒泡测试 ", false, true, true, true); +} + +void UITestInputEvent::UIKit_Pointer_Input_Test_Dispatch_Bubble_010() +{ + InnerBubbleDragTest("子不可拖拽父可拖拽有监听事件不消费冒泡测试 ", false, true, true, false); +} + +void UITestInputEvent::UIKit_Pointer_Input_Test_Dispatch_Key_Event_001() +{ + if (container_ != nullptr) { + UIViewGroup* uiViewGroup = new UIViewGroup(); + // 2: half of screen width; + uiViewGroup->SetPosition( + TEXT_DISTANCE_TO_LEFT_SIDE, positionY_, + (Screen::GetInstance().GetWidth() / 2 - TEXT_DISTANCE_TO_LEFT_SIDE), // 2: half of screen width; + 128); // 128: height + container_->Add(uiViewGroup); + + UILabel* label = new UILabel(); + uiViewGroup->Add(label); + // 2: half of screen width; + label->SetPosition(0, 0, Screen::GetInstance().GetWidth() / 2, TEXT_H); + label->SetText("物理按键事件测试 "); + label->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); + positionY_ += (TEXT_H + GAP); + UILabel* label1 = new UILabel(); + uiViewGroup->Add(label1); + label1->SetPosition(0, TEXT_H + GAP, TEXT_W, TEXT_H); + label1->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); + if (keyListener_ == nullptr) { + keyListener_ = new TestKeyInputListener(label1); + } + RootView::GetInstance()->SetOnKeyActListener(keyListener_); + positionY_ += ITEM_H; + } +} + +void UITestInputEvent::UIKit_Pointer_Input_Test_Dispatch_InVisible_Event_001() +{ + if (container_ != nullptr) { + UIViewGroup* uiViewGroup = new UIViewGroup(); + // 2: half of screen width; 36: decrease x-coordinate; 90: y-coordinate + uiViewGroup->SetPosition(TEXT_DISTANCE_TO_LEFT_SIDE, positionY_, 480, 128); // 480: width; 128: height + container_->Add(uiViewGroup); + UILabel* label = new UILabel(); + uiViewGroup->Add(label); + // 2: half of screen width; + label->SetPosition(0, 0, Screen::GetInstance().GetWidth() / 2, TEXT_H); + label->SetText("不可见对象事件传递测试 "); + label->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); + positionY_ = 0; + positionY_ += (TEXT_H + GAP * 2); // 2: double GAP + UIViewGroup* group1 = new UIViewGroup(); + uiViewGroup->Add(group1); + // 20: increase width 20: increase height + group1->SetPosition(positionX_, positionY_, TEST_VIEW_W + 20, TEST_VIEW_H + 20); + group1->SetStyle(STYLE_BACKGROUND_COLOR, Color::White().full); + group1->SetVisible(false); + TestView* testView = new TestView(); + group1->Add(testView); + testView->SetPosition(5, 5, TEST_VIEW_W, TEST_VIEW_H); // 5: position x 5:position y + testView->SetStyle(STYLE_BACKGROUND_COLOR, Color::Blue().full); + testView->SetTouchable(true); + testView->SetSentence("Click From test 0!"); + UIViewGroup* group2 = new UIViewGroup(); + uiViewGroup->Add(group2); + // 20: increase width 20: increase height + group2->SetPosition(0, positionY_, TEST_VIEW_W + 20, TEST_VIEW_H + 20); + group2->SetStyle(STYLE_BACKGROUND_COLOR, Color::White().full); + TestView* testView1 = new TestView(); + group2->Add(testView1); + testView1->SetPosition(5, 5, TEST_VIEW_W, TEST_VIEW_H); // 5: position x 5:position y + testView1->SetStyle(STYLE_BACKGROUND_COLOR, Color::Red().full); + testView1->SetTouchable(true); + testView1->SetSentence("Click From test 1!"); + UILabel* label1 = new UILabel(); + uiViewGroup->Add(label1); + // 50: increase width; 2:double GAP + label1->SetPosition(positionX_ + 50, positionY_ + 2 * GAP, TEXT_W, TEXT_H); + label1->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); + testView->SetLabel(label1); + testView1->SetLabel(label1); + positionY_ += ITEM_H; + } +} + +void UITestInputEvent::InnerTest(const char* title, bool touchable, bool draggable, bool dragParent) +{ + if (container_ != nullptr) { + UILabel* label = new UILabel(); + container_->Add(label); + // 2: half Screen width + label->SetPosition(positionX_, positionY_, Screen::GetInstance().GetWidth() / 2, TEXT_H); + label->SetText(title); + label->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); + positionY_ += (TEXT_H + GAP); + auto testView = new TestView(); + container_->Add(testView); + testView->SetPosition(positionX_, positionY_, TEST_VIEW_W, TEST_VIEW_H); + testView->SetStyle(STYLE_BACKGROUND_COLOR, Color::Blue().full); + testView->SetTouchable(touchable); + testView->SetDraggable(draggable); + testView->SetDragParentInstead(dragParent); + UILabel* label1 = new UILabel(); + container_->Add(label1); + label1->SetPosition(positionX_ + TEST_VIEW_GAP, positionY_ + 2 * GAP, TEXT_W, TEXT_H); // 2: double GAP + label1->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); + testView->SetLabel(label1); + positionY_ += ITEM_H; + } +} + +void UITestInputEvent::InnerBubbleTest(const char* title, + bool touchable, + bool draggable, + bool hasListener, + bool isBubble) +{ + if (container_ != nullptr) { + UILabel* label = new UILabel(); + container_->Add(label); + label->SetPosition((Screen::GetInstance().GetWidth() / 2 + TEXT_DISTANCE_TO_LEFT_SIDE), // 2: half screen width + positionY_, + (Screen::GetInstance().GetWidth() / 2 - TEXT_DISTANCE_TO_LEFT_SIDE), // 2: half screen width + TEXT_H); + label->SetText(title); + label->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); + positionY_ += (TEXT_H + GAP); + + OHOS::UIScrollView* parentContainer = new UIScrollView(); + // 2: half screen width + parentContainer->SetPosition(Screen::GetInstance().GetWidth() / 2 + TEXT_DISTANCE_TO_LEFT_SIDE, positionY_, + Screen::GetInstance().GetWidth() - TEXT_DISTANCE_TO_LEFT_SIDE, ITEM_H); + container_->Add(parentContainer); + TestView* testView = new TestView(); + parentContainer->Add(testView); + testView->SetPosition(0, 0, TEST_VIEW_W, TEST_VIEW_H); + testView->SetStyle(STYLE_BACKGROUND_COLOR, Color::Red().full); + testView->SetTouchable(touchable); + testView->SetDraggable(draggable); + testView->SetDragParentInstead(true); + UILabel* label1 = new UILabel(); + parentContainer->Add(label1); + label1->SetPosition(positionX_ + TEST_VIEW_GAP, 2 * GAP, TEXT_W, TEXT_H); // 2: tow gap + label1->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); + testView->SetLabel(label1); + + UILabel* label2 = new UILabel(); + parentContainer->Add(label2); + label2->SetPosition(positionX_ + 2 * TEST_VIEW_GAP, 2 * GAP, TEXT_W, TEXT_H); // 2: tow gap + label2->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); + testView->SetLabel2(label2); + + if (hasListener) { + UIView::OnClickListener* clickListenerParent = + new TestOnClickListener(label2, const_cast("l-parent click"), isBubble); + UIView::OnClickListener* clickListenerChild = + new TestOnClickListener(label1, const_cast("l-click"), isBubble); + testView->SetOnClickListener(clickListenerChild); + parentContainer->SetOnClickListener(clickListenerParent); + + UIView::OnLongPressListener* longTouchListenerParent = + new TestOnLongPressListener(label2, const_cast("l-parent long press"), isBubble); + UIView::OnLongPressListener* longTouchListenerChild = + new TestOnLongPressListener(label1, const_cast("l-long press"), isBubble); + testView->SetOnLongPressListener(longTouchListenerChild); + parentContainer->SetOnLongPressListener(longTouchListenerParent); + + UIView::OnTouchListener* touchListenerParent = new TestOnTouchListener( + label2, const_cast("l-parent press"), const_cast("l-parent release"), + const_cast("l-parent cancel"), isBubble); + UIView::OnTouchListener* touchListenerChild = + new TestOnTouchListener(label1, const_cast("l-press"), const_cast("l-release"), + const_cast("l-cancel"), isBubble); + testView->SetOnTouchListener(touchListenerChild); + parentContainer->SetOnTouchListener(touchListenerParent); + } + + positionY_ += ITEM_H; + } +} + +void UITestInputEvent::InnerBubbleDragTest(const char* title, + bool childDraggable, + bool parentDraggable, + bool hasListener, + bool isBubble) +{ + int itemH1 = ITEM_H * 2; // 2 times of ITEM_H + int itemH2 = itemH1 + ITEM_H; + int itemH3 = itemH2 + ITEM_H; + int halfScreenWith = Screen::GetInstance().GetWidth() / 2; // 2: half screen width + int offset = 30; // 40 pixel offset + + if (container_ != nullptr) { + UILabel* label = new UILabel(); + container_->Add(label); + // 2: half screen width + label->SetPosition(halfScreenWith + TEXT_DISTANCE_TO_LEFT_SIDE, positionY_, + halfScreenWith - TEXT_DISTANCE_TO_LEFT_SIDE, TEXT_H); + label->SetText(title); + label->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); + positionY_ += (TEXT_H + GAP); + + OHOS::TestUIScrollView* parentScroll = new TestUIScrollView(); + parentScroll->SetStyle(STYLE_BACKGROUND_COLOR, Color::Blue().full); + parentScroll->SetPosition(halfScreenWith + TEXT_DISTANCE_TO_LEFT_SIDE, positionY_, itemH1, itemH1); + parentScroll->SetThrowDrag(parentDraggable); + parentScroll->SetDraggable(parentDraggable); + container_->Add(parentScroll); + + OHOS::TestUIScrollView* childScroll = new TestUIScrollView(); + childScroll->SetStyle(STYLE_BACKGROUND_COLOR, Color::Red().full); + childScroll->SetPosition(offset, offset, itemH2, itemH2); + childScroll->SetThrowDrag(childDraggable); + childScroll->SetDraggable(childDraggable); + parentScroll->Add(childScroll); + + UILabelButton* button1 = new UILabelButton(); + button1->SetStyle(STYLE_BACKGROUND_COLOR, Color::Yellow().full); + button1->SetText("button1"); + button1->SetPosition(offset, offset, itemH3 * 2, itemH3); // 2: tow width + childScroll->Add(button1); + + UILabel* label1 = new UILabel(); + container_->Add(label1); + label1->SetPosition(itemH3 + offset + halfScreenWith, positionY_ + 2 * GAP, TEXT_W, TEXT_H); // 2: tow gap + label1->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); + childScroll->SetLabel(label1); + + UILabel* label2 = new UILabel(); + container_->Add(label2); + label2->SetPosition(itemH3 + offset + halfScreenWith, positionY_ + 6 * GAP, TEXT_W, TEXT_H); // 6: tow gap + label2->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); + parentScroll->SetLabel(label2); + + if (hasListener) { + UIView::OnClickListener* clickListenerParent = + new TestOnClickListener(label2, const_cast("l-parent click"), isBubble); + UIView::OnClickListener* clickListenerChild = + new TestOnClickListener(label1, const_cast("l-click"), isBubble); + childScroll->SetOnClickListener(clickListenerChild); + parentScroll->SetOnClickListener(clickListenerParent); + + UIView::OnLongPressListener* longTouchListenerParent = + new TestOnLongPressListener(label2, const_cast("l-parent long press"), isBubble); + UIView::OnLongPressListener* longTouchListenerChild = + new TestOnLongPressListener(label1, const_cast("l-long press"), isBubble); + childScroll->SetOnLongPressListener(longTouchListenerChild); + parentScroll->SetOnLongPressListener(longTouchListenerParent); + + UIView::OnTouchListener* touchListenerParent = new TestOnTouchListener( + label2, const_cast("l-parent press"), const_cast("l-parent release"), + const_cast("l-parent cancel"), isBubble); + UIView::OnTouchListener* touchListenerChild = + new TestOnTouchListener(label1, const_cast("l-press"), const_cast("l-release"), + const_cast("l-cancel"), isBubble); + childScroll->SetOnTouchListener(touchListenerChild); + parentScroll->SetOnTouchListener(touchListenerParent); + + UIView::OnDragListener* dragListenerParent = new TestOnDragListener( + label2, const_cast("l-dragStart parent"), const_cast("l-drag parent"), + const_cast("l-dragEnd parent"), isBubble); + UIView::OnDragListener* dragListenerChild = + new TestOnDragListener(label1, const_cast("l-dragStart"), const_cast("l-drag"), + const_cast("l-dragEnd"), isBubble); + childScroll->SetOnDragListener(dragListenerChild); + parentScroll->SetOnDragListener(dragListenerParent); + } + positionY_ += itemH1; + } +} +} // namespace OHOS diff --git a/test/uitest/test_input_event/ui_test_input_event.h b/test/uitest/test_input_event/ui_test_input_event.h new file mode 100755 index 0000000..c2acebd --- /dev/null +++ b/test/uitest/test_input_event/ui_test_input_event.h @@ -0,0 +1,252 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef UI_TEST_INPUT_EVENT_H +#define UI_TEST_INPUT_EVENT_H + +#include "components/root_view.h" +#include "components/ui_label.h" +#include "components/ui_label_button.h" +#include "components/ui_scroll_view.h" +#include "ui_test.h" + +namespace OHOS { +class TestKeyInputListener : public RootView::OnKeyActListener { +public: + explicit TestKeyInputListener(UILabel* label) : label_(label) {} + virtual ~TestKeyInputListener() {} + bool OnKeyAct(UIView& view, const KeyEvent& event) override + { + if (label_ != nullptr) { + label_->SetText("key pressed!"); + label_->Invalidate(); + } + return true; + } + +private: + UILabel* label_; +}; + +class TestOnClickListener : public UIView::OnClickListener { +public: + explicit TestOnClickListener(UILabel* label, char* sentence, bool isConsume) + : label_(label), sentence_(sentence), isConsume_(isConsume) {} + virtual ~TestOnClickListener() {} + virtual bool OnClick(UIView& view, const ClickEvent& event) + { + if (label_ != nullptr) { + label_->SetText(sentence_); + label_->Invalidate(); + } + return isConsume_; + } + +private: + UILabel* label_; + char* sentence_; + bool isConsume_; +}; + +class TestOnLongPressListener : public UIView::OnLongPressListener { +public: + explicit TestOnLongPressListener(UILabel* label, char* sentence, bool isConsume) + : label_(label), sentence_(sentence), isConsume_(isConsume) {} + virtual ~TestOnLongPressListener() {} + virtual bool OnLongPress(UIView& view, const LongPressEvent& event) + { + if (label_ != nullptr) { + label_->SetText(sentence_); + label_->Invalidate(); + } + return isConsume_; + } + +private: + UILabel* label_; + char* sentence_; + bool isConsume_; +}; + +class TestOnTouchListener : public UIView::OnTouchListener { +public: + explicit TestOnTouchListener(UILabel* label, char* strPress, char* strRelease, char* strCancel, bool isConsume) + : label_(label), strPress_(strPress), strRelease_(strRelease), strCancel_(strCancel), isConsume_(isConsume) {} + virtual ~TestOnTouchListener() {} + virtual bool OnPress(UIView& view, const PressEvent& event) + { + if (label_ != nullptr) { + label_->SetText(strPress_); + label_->Invalidate(); + } + return isConsume_; + } + + virtual bool OnRelease(UIView& view, const ReleaseEvent& event) + { + if (label_ != nullptr) { + label_->SetText(strRelease_); + label_->Invalidate(); + } + return isConsume_; + } + + virtual bool OnCancel(UIView& view, const CancelEvent& event) + { + if (label_ != nullptr) { + label_->SetText(strCancel_); + label_->Invalidate(); + } + return isConsume_; + } + +private: + UILabel* label_; + char* strPress_; + char* strRelease_; + char* strCancel_; + bool isConsume_; +}; + +class TestOnDragListener : public UIView::OnDragListener { +public: + explicit TestOnDragListener(UILabel* label, char* strDragStart, char* strDrag, char* strDragEnd, bool isConsume) + : label_(label), strDragStart_(strDragStart), strDrag_(strDrag), strDragEnd_(strDragEnd), isConsume_(isConsume) + { + } + virtual ~TestOnDragListener() {} + virtual bool OnDragStart(UIView& view, const DragEvent& event) + { + if (label_ != nullptr) { + label_->SetText(strDragStart_); + label_->Invalidate(); + } + return isConsume_; + } + + virtual bool OnDrag(UIView& view, const DragEvent& event) + { + if (label_ != nullptr) { + label_->SetText(strDrag_); + label_->Invalidate(); + } + return isConsume_; + } + + virtual bool OnDragEnd(UIView& view, const DragEvent& event) + { + if (label_ != nullptr) { + label_->SetText(strDragEnd_); + label_->Invalidate(); + } + return isConsume_; + } + +private: + UILabel* label_; + char* strDragStart_; + char* strDrag_; + char* strDragEnd_; + bool isConsume_; +}; + + +class UITestInputEvent : public UITest { +public: + UITestInputEvent() {} + ~UITestInputEvent() {} + void SetUp() override; + void TearDown() override; + UIView* GetTestView() override; + + /** + * @brief Test if dispatch press\release\longpress\cancel event act normal when target is touchable + */ + void UIKit_Pointer_Input_Test_Dispatch_Simple_Event_001(); + /** + * @brief Test if dispatch press\release\longpress\cancel\drag event act normal when target is untouchable + */ + void UIKit_Pointer_Input_Test_Dispatch_Simple_Event_002(); + /** + * @brief Test if dispatch drag event act normal when target is touchable and draggable and drag parent instead. + */ + void UIKit_Pointer_Input_Test_Dispatch_Drag_Event_001(); + /** + * @brief Test if dispatch drag event act normal when target is touchable and draggable and not drag parent instead. + */ + void UIKit_Pointer_Input_Test_Dispatch_Drag_Event_002(); + /** + * @brief Test if dispatch drag event act normal when target is untouchable but draggable. + */ + void UIKit_Pointer_Input_Test_Dispatch_Drag_Event_003(); + /** + * @brief Test if dispatch drag event act normal when target is untouchable but draggable. + */ + void UIKit_Pointer_Input_Test_Dispatch_Key_Event_001(); + /** + * @brief Test if dispatch drag event act normal when target is untouchable but draggable. + */ + void UIKit_Pointer_Input_Test_Dispatch_InVisible_Event_001(); + /** + * @brief Test click, release or longClick event bubble act normal when both of parent and child is triggered. + */ + void UIKit_Pointer_Input_Test_Dispatch_Bubble_001(); + /** + * @brief Test click, release or longClick event bubble act normal when child is triggered but and parent not. + */ + void UIKit_Pointer_Input_Test_Dispatch_Bubble_002(); + /** + * @brief Test click, release or longClick event bubble act normal when child is triggered but and parent not. + */ + void UIKit_Pointer_Input_Test_Dispatch_Bubble_003(); + /** + * @brief Test click, release or longClick event bubble act normal when parent is triggered but and child not. + */ + void UIKit_Pointer_Input_Test_Dispatch_Bubble_004(); + /** + * @brief Test drag event bubble act normal when both of parent and child is triggered. + */ + void UIKit_Pointer_Input_Test_Dispatch_Bubble_005(); + /** + * @brief Test drag event bubble act normal when child is triggered but and parent not. + */ + void UIKit_Pointer_Input_Test_Dispatch_Bubble_006(); + /** + * @brief Test drag event bubble act normal when child is triggered but and parent not. + */ + void UIKit_Pointer_Input_Test_Dispatch_Bubble_007(); + /** + * @brief Test drag event bubble act normal when both of parent and child is not triggered. + */ + void UIKit_Pointer_Input_Test_Dispatch_Bubble_008(); + /** + * @brief Test drag event bubble act normal when parent is triggered but and child not. + */ + void UIKit_Pointer_Input_Test_Dispatch_Bubble_009(); + /** + * @brief Test drag event bubble act normal when parent is triggered but and child not. + */ + void UIKit_Pointer_Input_Test_Dispatch_Bubble_010(); + +private: + UIScrollView* container_ = nullptr; + TestKeyInputListener* keyListener_ = nullptr; + void InnerTest(const char* title, bool touchable, bool draggable, bool dragParent); + void InnerBubbleTest(const char* title, bool touchable, bool draggable, bool hasListener, bool isBubble); + void InnerBubbleDragTest(const char* title, bool childDraggable, bool parentDraggable, bool hasListener, + bool isBubble); +}; +} // namespace OHOS +#endif // UI_TEST_INPUT_EVENT_H diff --git a/test/uitest/test_label/ui_test_label.cpp b/test/uitest/test_label/ui_test_label.cpp new file mode 100755 index 0000000..ee1d617 --- /dev/null +++ b/test/uitest/test_label/ui_test_label.cpp @@ -0,0 +1,280 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "ui_test_label.h" +#include "common/screen.h" +#include "components/ui_checkbox.h" +#include "components/ui_label.h" +#include "font/ui_font.h" + +namespace OHOS { +namespace { +const int16_t GAP = 5; +const int16_t TITLE_HEIGHT = 20; +const uint16_t LABEL_WIDTH = 350; +const uint16_t LABEL_HEIGHT = 50; +} // namespace + +void UITestLabel::SetUp() +{ + if (container_ == nullptr) { + container_ = new UIScrollView(); + container_->SetThrowDrag(true); + container_->SetHorizontalScrollState(false); + container_->Resize(Screen::GetInstance().GetWidth(), Screen::GetInstance().GetHeight() - BACK_BUTTON_HEIGHT); + positionX_ = 0; + positionY_ = 0; + } +} + +void UITestLabel::TearDown() +{ + DeleteChildren(container_); + container_ = nullptr; + uiLabel = nullptr; + labelFontSizeBtn1_ = nullptr; + labelFontSizeBtn2_ = nullptr; + labelFontSizeBtn3_ = nullptr; + labelHorAlignBtn1_ = nullptr; + labelHorAlignBtn2_ = nullptr; + labelHorAlignBtn3_ = nullptr; + labelColorBtn1_ = nullptr; + labelColorBtn2_ = nullptr; + labelColorBtn3_ = nullptr; + labelBeyondBtn1_ = nullptr; + labelBeyondBtn2_ = nullptr; + labelBeyondBtn3_ = nullptr; + labelLineBtn1_ = nullptr; + labelLineBtn2_ = nullptr; + labelVerAlignlBtn1_ = nullptr; + labelVerAlignlBtn2_ = nullptr; + labelVerAlignlBtn3_ = nullptr; + labelDirectionBtn1_ = nullptr; + labelDirectionBtn2_ = nullptr; + labelSizeBtn1_ = nullptr; + labelSizeBtn2_ = nullptr; +} + +UIView* UITestLabel::GetTestView() +{ + UIKit_UILabel_Test_Display_001(); + UIKit_UILabel_Test_Display_002(); + UIKit_UILabel_Test_Display_003(); + return container_; +} + +void UITestLabel::UIKit_UILabel_Test_Display_001() +{ + if (container_ != nullptr) { + UIViewGroup* uiViewGroup = new UIViewGroup(); + // 320: width; 390: height + uiViewGroup->SetPosition(positionX_, positionY_, 320, 390); + container_->Add(uiViewGroup); + UILabel* label = new UILabel(); + uiViewGroup->Add(label); + // 288: width; 48: height + label->SetPosition(TEXT_DISTANCE_TO_LEFT_SIDE, TEXT_DISTANCE_TO_TOP_SIDE, 288, 48); + label->SetText("UILabel效果"); + label->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); + UIViewGroup* uiViewGroupFrame = new UIViewGroup(); + uiViewGroup->Add(uiViewGroupFrame); + // 288: width; 336: height + uiViewGroupFrame->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE2, VIEW_DISTANCE_TO_TOP_SIDE, 288, 336); + uiViewGroupFrame->SetStyle(STYLE_BORDER_COLOR, Color::White().full); + uiViewGroupFrame->SetStyle(STYLE_BORDER_OPA, HALF_OPA_OPAQUE); + uiViewGroupFrame->SetStyle(STYLE_BORDER_WIDTH, VIEW_STYLE_BORDER_WIDTH); + uiViewGroupFrame->SetStyle(STYLE_BORDER_RADIUS, VIEW_STYLE_BORDER_RADIUS); + uiViewGroupFrame->SetStyle(STYLE_BACKGROUND_OPA, 0); + uiLabel = new UILabel(); + uiLabel->SetText("鸿蒙轻量级图形子系统"); + uiLabel->SetFont(DEFAULT_VECTOR_FONT_FILENAME, 24); // 24: font size + uiLabel->SetPosition(0, 141, 280, 336); // 141: y-coordinate; 280: width; 336: height + uiViewGroupFrame->Add(uiLabel); + positionX_ += 336; // 336: x-coordinate + + UIViewGroup* uiViewGroup2 = new UIViewGroup(); + uiViewGroup2->SetPosition(positionX_, 0, 300, 384); // 300: width; 384: height + container_->Add(uiViewGroup2); + CreateLabels(uiViewGroup2); + } +} + +void UITestLabel::CreateLabels(UIViewGroup* uiViewGroup) +{ + if (uiViewGroup == nullptr) { + return; + } + UILabel* label1 = new UILabel(); + uiViewGroup->Add(label1); + // 288: width; 48: height + label1->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE2, TEXT_DISTANCE_TO_TOP_SIDE, 288, 48); + label1->SetText("字号"); + label1->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); + labelFontSizeBtn1_ = SetUpButton("18 ", 24, 48, uiViewGroup); // 24: x-coordinate; 48: y-coordinate + labelFontSizeBtn2_ = SetUpButton("24", 116, 48, uiViewGroup); // 116: x-coordinate; 48: y-coordinate + labelFontSizeBtn3_ = SetUpButton("30", 208, 48, uiViewGroup); // 208: x-coordinate; 48: y-coordinate + + UILabel* label2 = new UILabel(); + uiViewGroup->Add(label2); + label2->SetPosition(24, 107, 288, 48); // 24: x-coordinate, 107: y-coordinate, 288: width; 48: height + label2->SetText("水平对齐方式"); + label2->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); + labelHorAlignBtn1_ = SetUpButton("左对齐 ", 24, 144, uiViewGroup); // 24: x-coordinate; 144: y-coordinate + labelHorAlignBtn2_ = SetUpButton("中对齐 ", 116, 144, uiViewGroup); // 116: x-coordinate; 144: y-coordinate + labelHorAlignBtn3_ = SetUpButton("右对齐 ", 208, 144, uiViewGroup); // 208: x-coordinate; 144: y-coordinate + + UILabel* label3 = new UILabel(); + uiViewGroup->Add(label3); + label3->SetPosition(24, 203, 288, 48); // 24: x-coordinate, 203: y-coordinate, 288: width; 48: height + label3->SetText("颜色"); + label3->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); + labelColorBtn1_ = SetUpButton("白色 ", 24, 240, uiViewGroup); // 24: x-coordinate; 240: y-coordinate + labelColorBtn2_ = SetUpButton("变色 ", 116, 240, uiViewGroup); // 116: x-coordinate; 240: y-coordinate + labelColorBtn3_ = SetUpButton("半透明 ", 208, 240, uiViewGroup); // 208: x-coordinate; 240: y-coordinate + + UILabel* label4 = new UILabel(); + uiViewGroup->Add(label4); + label4->SetPosition(24, 299, 288, 48); // 24: x-coordinate, 299: y-coordinate, 288: width; 48: height + label4->SetText("超出处理"); + label4->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); + labelBeyondBtn1_ = SetUpButton("截断 ", 24, 336, uiViewGroup); // 24: x-coordinate; 336: y-coordinate + labelBeyondBtn2_ = SetUpButton("省略 ", 116, 336, uiViewGroup); // 116: x-coordinate; 336: y-coordinate + labelBeyondBtn3_ = SetUpButton("滚动 ", 208, 336, uiViewGroup); // 208: x-coordinate; 336: y-coordinate + positionX_ += 312; // 312: increase y-coordinate +} + +void UITestLabel::UIKit_UILabel_Test_Display_002() +{ + if (container_ != nullptr) { + UIViewGroup* uiViewGroup = new UIViewGroup(); + uiViewGroup->SetPosition(positionX_, positionY_, 320, 390); // 320: width; 390: height + container_->Add(uiViewGroup); + UILabel* label = new UILabel(); + uiViewGroup->Add(label); + // 288: width; 48: height + label->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE2, TEXT_DISTANCE_TO_TOP_SIDE, 288, 48); + label->SetText("行数"); + label->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); + labelLineBtn1_ = SetUpButton("单行 ", 24, 48, uiViewGroup); // 24: x-coordinate; 48: y-coordinate + labelLineBtn2_ = SetUpButton("多行 ", 116, 48, uiViewGroup); // 116: x-coordinate; 48: y-coordinate + UILabel* label2 = new UILabel(); + uiViewGroup->Add(label2); + label2->SetPosition(24, 107, 288, 48); // 24: x-coordinate, 107: y-coordinate, 288: width; 48: height + label2->SetText("竖直对齐方式"); + label2->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); + labelVerAlignlBtn1_ = SetUpButton("上对齐 ", 24, 144, uiViewGroup); // 24: x-coordinate; 144: y-coordinate + labelVerAlignlBtn2_ = SetUpButton("中对齐 ", 116, 144, uiViewGroup); // 116: x-coordinate; 144: y-coordinate + labelVerAlignlBtn3_ = SetUpButton("下对齐 ", 208, 144, uiViewGroup); // 208: x-coordinate; 144: y-coordinate + UILabel* label3 = new UILabel(); + uiViewGroup->Add(label3); + label3->SetPosition(24, 203, 288, 48); // 24: x-coordinate, 203: y-coordinate, 288: width; 48: height + label3->SetText("方向"); + label3->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); + labelDirectionBtn1_ = SetUpButton("左往右 ", 24, 240, uiViewGroup); // 24: x-coordinate; 240: y-coordinate + labelDirectionBtn2_ = SetUpButton("右往左 ", 116, 240, uiViewGroup); // 116: x-coordinate; 240: y-coordinate + positionY_ += 384; // 384: increase x-coordinate + positionX_ -= 312; // 312: increase y-coordinate + } +} + +void UITestLabel::UIKit_UILabel_Test_Display_003() +{ + if (container_ != nullptr) { + UIViewGroup* uiViewGroup = new UIViewGroup(); + uiViewGroup->SetPosition(positionX_, positionY_, 450, 110); // 450: width; 110: height + container_->Add(uiViewGroup); + UILabel* label = new UILabel(); + uiViewGroup->Add(label); + label->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE2, TEXT_DISTANCE_TO_TOP_SIDE, 420, 48); // 420: width; 48: height + label->SetText("Label大小"); + label->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); + // 24: x-coordinate; 48: y-coordinate; 120: width + labelSizeBtn1_ = SetUpButton("动态宽度 ", 24, 48, uiViewGroup, 120); + // 156: x-coordinate; 48: y-coordinate; 120: width + labelSizeBtn2_ = SetUpButton("动态高度 ", 156, 48, uiViewGroup, 120); + } +} + +bool UITestLabel::OnClick(UIView& view, const ClickEvent& event) +{ + uiLabel->Resize(288, 100); // 288: width; 100: height + uiLabel->SetFont(DEFAULT_VECTOR_FONT_FILENAME, 24); // 24: font size + if (&view == labelFontSizeBtn1_) { + uiLabel->SetFont(DEFAULT_VECTOR_FONT_FILENAME, 18); // 18: font size + } else if (&view == labelFontSizeBtn2_) { + uiLabel->SetFont(DEFAULT_VECTOR_FONT_FILENAME, 24); // 24: font size + } else if (&view == labelFontSizeBtn3_) { + uiLabel->SetFont(DEFAULT_VECTOR_FONT_FILENAME, 30); // 30: font size + } else if (&view == labelHorAlignBtn1_) { + uiLabel->SetAlign(UITextLanguageAlignment::TEXT_ALIGNMENT_LEFT); + } else if (&view == labelHorAlignBtn2_) { + uiLabel->SetAlign(UITextLanguageAlignment::TEXT_ALIGNMENT_CENTER); + } else if (&view == labelHorAlignBtn3_) { + uiLabel->SetAlign(UITextLanguageAlignment::TEXT_ALIGNMENT_RIGHT); + } else if (&view == labelColorBtn1_) { + uiLabel->SetStyle(STYLE_TEXT_COLOR, Color::White().full); + uiLabel->SetStyle(STYLE_TEXT_OPA, OPA_OPAQUE); + } else if (&view == labelColorBtn2_) { + uiLabel->SetStyle(STYLE_TEXT_COLOR, Color::Red().full); + uiLabel->SetStyle(STYLE_TEXT_OPA, OPA_OPAQUE); + } else if (&view == labelColorBtn3_) { + uiLabel->SetStyle(STYLE_TEXT_OPA, 127); // 127: opaque + } else if (&view == labelBeyondBtn1_) { + uiLabel->Resize(288, 35); // 288: width; 35: height + uiLabel->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); + uiLabel->SetText("鸿蒙轻量级图形子系统,鸿蒙轻量级图形子系统 "); + uiLabel->SetLineBreakMode(UILabel::LINE_BREAK_CLIP); + } else if (&view == labelBeyondBtn2_) { + uiLabel->Resize(288, 35); // 288: width; 35: height + uiLabel->SetText("鸿蒙轻量级图形子系统,鸿蒙轻量级图形子系统 "); + uiLabel->SetLineBreakMode(UILabel::LINE_BREAK_ELLIPSIS); + } else if (&view == labelBeyondBtn3_) { + uiLabel->SetText("鸿蒙轻量级图形子系统,鸿蒙轻量级图形子系统 "); + uiLabel->SetLineBreakMode(UILabel::LINE_BREAK_MARQUEE); + } else { + ExpandClick(view, event); + } + return true; +} + +void UITestLabel::ExpandClick(UIView& view, const ClickEvent& event) const +{ + if (&view == labelLineBtn1_) { + uiLabel->Resize(288, 50); // 288: width; 50: height + uiLabel->SetFont(DEFAULT_VECTOR_FONT_FILENAME, 30); // 30:font size + uiLabel->SetLineBreakMode(UILabel::LINE_BREAK_ELLIPSIS); + } else if (&view == labelLineBtn2_) { + uiLabel->Resize(288, 100); // 288: width; 100: height + uiLabel->SetFont(DEFAULT_VECTOR_FONT_FILENAME, 30); // 30:font size + uiLabel->SetLineBreakMode(UILabel::LINE_BREAK_ELLIPSIS); + } else if (&view == labelVerAlignlBtn1_) { + uiLabel->SetAlign(UITextLanguageAlignment::TEXT_ALIGNMENT_LEFT, UITextLanguageAlignment::TEXT_ALIGNMENT_TOP); + } else if (&view == labelVerAlignlBtn2_) { + uiLabel->SetAlign(UITextLanguageAlignment::TEXT_ALIGNMENT_LEFT, UITextLanguageAlignment::TEXT_ALIGNMENT_CENTER); + } else if (&view == labelVerAlignlBtn3_) { + uiLabel->SetAlign(UITextLanguageAlignment::TEXT_ALIGNMENT_LEFT, UITextLanguageAlignment::TEXT_ALIGNMENT_BOTTOM); + } else if (&view == labelDirectionBtn1_) { + uiLabel->SetDirect(TEXT_DIRECT_LTR); + } else if (&view == labelDirectionBtn2_) { + uiLabel->SetDirect(TEXT_DIRECT_RTL); + } else if (&view == labelSizeBtn1_) { + uiLabel->SetText("鸿蒙轻量级图形子系统,鸿蒙轻量级图形子系统 "); + uiLabel->SetLineBreakMode(UILabel::LINE_BREAK_ADAPT); + } else if (&view == labelSizeBtn2_) { + uiLabel->SetText("鸿蒙轻量级图形子系统,鸿蒙轻量级图形子系统 "); + uiLabel->SetLineBreakMode(UILabel::LINE_BREAK_WRAP); + } +} +} // namespace OHOS \ No newline at end of file diff --git a/test/uitest/test_label/ui_test_label.h b/test/uitest/test_label/ui_test_label.h new file mode 100755 index 0000000..25bc732 --- /dev/null +++ b/test/uitest/test_label/ui_test_label.h @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef UI_TEST_LABEL_H +#define UI_TEST_LABEL_H + +#include "components/ui_label.h" +#include "components/ui_label_button.h" +#include "components/ui_scroll_view.h" +#include "ui_test.h" + +namespace OHOS { +class UITestLabel : public UITest, public UIView::OnClickListener { +public: + UITestLabel() {} + ~UITestLabel() {} + void SetUp() override; + void TearDown() override; + UIView* GetTestView() override; + void CreateLabels(UIViewGroup* uiViewGroup); + + /** + * @brief Test display dynamic text + */ + void UIKit_UILabel_Test_Display_001(); + void UIKit_UILabel_Test_Display_002(); + void UIKit_UILabel_Test_Display_003(); + + bool OnClick(UIView& view, const ClickEvent& event) override; + void ExpandClick(UIView& view, const ClickEvent& event) const; + +private: + UIScrollView* container_ = nullptr; + UILabel* uiLabel = nullptr; + UILabelButton* labelFontSizeBtn1_ = nullptr; + UILabelButton* labelFontSizeBtn2_ = nullptr; + UILabelButton* labelFontSizeBtn3_ = nullptr; + UILabelButton* labelHorAlignBtn1_ = nullptr; + UILabelButton* labelHorAlignBtn2_ = nullptr; + UILabelButton* labelHorAlignBtn3_ = nullptr; + UILabelButton* labelColorBtn1_ = nullptr; + UILabelButton* labelColorBtn2_ = nullptr; + UILabelButton* labelColorBtn3_ = nullptr; + UILabelButton* labelBeyondBtn1_ = nullptr; + UILabelButton* labelBeyondBtn2_ = nullptr; + UILabelButton* labelBeyondBtn3_ = nullptr; + UILabelButton* labelLineBtn1_ = nullptr; + UILabelButton* labelLineBtn2_ = nullptr; + UILabelButton* labelVerAlignlBtn1_ = nullptr; + UILabelButton* labelVerAlignlBtn2_ = nullptr; + UILabelButton* labelVerAlignlBtn3_ = nullptr; + UILabelButton* labelDirectionBtn1_ = nullptr; + UILabelButton* labelDirectionBtn2_ = nullptr; + UILabelButton* labelSizeBtn1_ = nullptr; + UILabelButton* labelSizeBtn2_ = nullptr; + + void InnerTestTitle(const char* title); + UILabelButton* SetUpButton(const char* title, int16_t x, int16_t y, UIViewGroup* uiViewGroup, + int16_t width = 80, int16_t height = 40) + { + if (uiViewGroup == nullptr) { + return nullptr; + } + UILabelButton* btn = new UILabelButton(); + btn->SetPosition(x, y, width, height); + btn->SetText(title); + btn->SetFont(DEFAULT_VECTOR_FONT_FILENAME, BUTTON_LABEL_SIZE); + btn->SetOnClickListener(this); + btn->SetStyleForState(STYLE_BORDER_RADIUS, BUTTON_STYLE_BORDER_RADIUS_VALUE, UIButton::RELEASED); + btn->SetStyleForState(STYLE_BORDER_RADIUS, BUTTON_STYLE_BORDER_RADIUS_VALUE, UIButton::PRESSED); + btn->SetStyleForState(STYLE_BORDER_RADIUS, BUTTON_STYLE_BORDER_RADIUS_VALUE, UIButton::INACTIVE); + btn->SetStyleForState(STYLE_BACKGROUND_COLOR, BUTTON_STYLE_BACKGROUND_COLOR_VALUE, UIButton::RELEASED); + btn->SetStyleForState(STYLE_BACKGROUND_COLOR, BUTTON_STYLE_BACKGROUND_COLOR_VALUE, UIButton::PRESSED); + btn->SetStyleForState(STYLE_BACKGROUND_COLOR, BUTTON_STYLE_BACKGROUND_COLOR_VALUE, UIButton::INACTIVE); + uiViewGroup->Add(btn); + return btn; + } +}; +} // namespace OHOS +#endif // UI_TEST_LABEL_H diff --git a/test/uitest/test_layout/ui_test_advanced_layout.cpp b/test/uitest/test_layout/ui_test_advanced_layout.cpp new file mode 100755 index 0000000..f7776e2 --- /dev/null +++ b/test/uitest/test_layout/ui_test_advanced_layout.cpp @@ -0,0 +1,284 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "ui_test_advanced_layout.h" +#include "common/screen.h" + +namespace OHOS { +namespace { +const int16_t TEXT_H = 20; +const int16_t TEXT_W = 250; +const int16_t TEST_VIEW_H = 40; +const int16_t TEST_VIEW_W = 40; +const int16_t GAP = 5; +const int16_t TEST_VIEW_GAP = 80; +} // namespace + +void UITestAdvancedLayout::SetUp() +{ + container_ = new UIScrollView(); + flexController_ = new GridLayout(); + fTarget_ = new FlexLayout(); + resetfBtn_ = new UILabelButton(); + marginfBtn_ = new UILabelButton(); + + horfBtn_ = new UILabelButton(); + horfRBtn_ = new UILabelButton(); + verfBtn_ = new UILabelButton(); + verfRBtn_ = new UILabelButton(); + wrapBtn_ = new UILabelButton(); + addElefBtn_ = new UILabelButton(); + majorStartBtn_ = new UILabelButton(); + majorEndBtn_ = new UILabelButton(); + majorCenterBtn_ = new UILabelButton(); + majorEvenBtn_ = new UILabelButton(); + majorAroundBtn_ = new UILabelButton(); + majorBetBtn_ = new UILabelButton(); + secStartBtn_ = new UILabelButton(); + secEndBtn_ = new UILabelButton(); + secCenterBtn_ = new UILabelButton(); + secInvalidBtn_ = new UILabelButton(); + layoutChildrenfBtn_ = new UILabelButton(); + + gridController_ = new GridLayout(); + gTarget_ = new GridLayout(); + horgBtn_ = new UILabelButton(); + horgRBtn_ = new UILabelButton(); + vergBtn_ = new UILabelButton(); + vergRBtn_ = new UILabelButton(); + incRowsBtn_ = new UILabelButton(); + decRowsBtn_ = new UILabelButton(); + incColsBtn_ = new UILabelButton(); + decColsBtn_ = new UILabelButton(); + addElegBtn_ = new UILabelButton(); + resetgBtn_ = new UILabelButton(); + margingBtn_ = new UILabelButton(); + layoutChildrengBtn_ = new UILabelButton(); + container_->Resize(Screen::GetInstance().GetWidth(), Screen::GetInstance().GetHeight() - BACK_BUTTON_HEIGHT); + positionX_ = 20; // 20: position x + positionY_ = 5; // 5: position y +} + +void UITestAdvancedLayout::TearDown() +{ + DeleteChildren(container_); + container_ = nullptr; +} + +UIView* UITestAdvancedLayout::GetTestView() +{ + UIKit_Layout_Test_FlexLayout_001(); + UIKit_Layout_Test_GridLayout_001(); + return container_; +} + +void UITestAdvancedLayout::UIKit_Layout_Test_FlexLayout_001() +{ + if (container_ != nullptr) { + UIViewGroup* uiViewGroup = new UIViewGroup(); + uiViewGroup->SetPosition(0, 0, Screen::GetInstance().GetWidth(), 420); // 420: height + container_->Add(uiViewGroup); + UILabel* label = new UILabel(); + uiViewGroup->Add(label); + // 288: width; 48: height + label->SetPosition(TEXT_DISTANCE_TO_LEFT_SIDE, TEXT_DISTANCE_TO_TOP_SIDE, 288, 48); + label->SetText("Flex布局效果"); + label->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); + UIViewGroup* uiViewGroupFrame = new UIViewGroup(); + uiViewGroup->Add(uiViewGroupFrame); + uiViewGroupFrame->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE2, VIEW_DISTANCE_TO_TOP_SIDE, + Screen::GetInstance().GetWidth() - VIEW_DISTANCE_TO_LEFT_SIDE, + 100); // 100: height + uiViewGroupFrame->SetStyle(STYLE_BORDER_COLOR, Color::White().full); + uiViewGroupFrame->SetStyle(STYLE_BORDER_OPA, HALF_OPA_OPAQUE); + uiViewGroupFrame->SetStyle(STYLE_BORDER_WIDTH, VIEW_STYLE_BORDER_WIDTH); + uiViewGroupFrame->SetStyle(STYLE_BORDER_RADIUS, VIEW_STYLE_BORDER_RADIUS); + uiViewGroupFrame->SetStyle(STYLE_BACKGROUND_OPA, 0); + uiViewGroupFrame->Add(fTarget_); + + fTarget_->SetPosition(0, 0, Screen::GetInstance().GetWidth() - VIEW_DISTANCE_TO_LEFT_SIDE, 100); // 100: height + fTarget_->SetStyle(STYLE_BACKGROUND_OPA, 100); // 100: opacity + + positionY_ += 160; // 160: position y add + uiViewGroup->Add(flexController_); + flexController_->SetPosition(0, positionY_, Screen::GetInstance().GetWidth(), 250); // 250: height + flexController_->SetLayoutDirection(LAYOUT_HOR); + flexController_->SetRows(5); // 5: row + flexController_->SetCols(4); // 4: col + + SetUpButton(flexController_, resetfBtn_, "reset"); + SetUpButton(flexController_, marginfBtn_, "margin"); + SetUpButton(flexController_, horfBtn_, "hor"); + SetUpButton(flexController_, horfRBtn_, "hor_r"); + SetUpButton(flexController_, verfBtn_, "ver"); + SetUpButton(flexController_, verfRBtn_, "ver_r"); + SetUpButton(flexController_, wrapBtn_, "wrap"); + SetUpButton(flexController_, addElefBtn_, "add"); + SetUpButton(flexController_, majorStartBtn_, "M_start"); + SetUpButton(flexController_, majorEndBtn_, "M_end"); + SetUpButton(flexController_, majorCenterBtn_, "M_center"); + SetUpButton(flexController_, majorEvenBtn_, "M_even"); + SetUpButton(flexController_, majorAroundBtn_, "M_around"); + SetUpButton(flexController_, majorBetBtn_, "M_between"); + SetUpButton(flexController_, secStartBtn_, "S_start"); + SetUpButton(flexController_, secEndBtn_, "S_end"); + SetUpButton(flexController_, secCenterBtn_, "S_center"); + SetUpButton(flexController_, secInvalidBtn_, "S_invalid"); + SetUpButton(flexController_, layoutChildrenfBtn_, "布局"); + flexController_->LayoutChildren(); + positionY_ += 250; // 250: position y add + } +} + +void UITestAdvancedLayout::UIKit_Layout_Test_GridLayout_001() +{ + if (container_ != nullptr) { + UIViewGroup* uiViewGroup = new UIViewGroup(); + uiViewGroup->SetPosition(0, positionY_, Screen::GetInstance().GetWidth(), 370); // 370: height + container_->Add(uiViewGroup); + UILabel* label = new UILabel(); + uiViewGroup->Add(label); + // 288: widht; 48: height + label->SetPosition(TEXT_DISTANCE_TO_LEFT_SIDE, TEXT_DISTANCE_TO_TOP_SIDE, 288, 48); + label->SetText("Grid布局测试"); + label->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); + UIViewGroup* uiViewGroupFrame = new UIViewGroup(); + uiViewGroup->Add(uiViewGroupFrame); + uiViewGroupFrame->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE2, VIEW_DISTANCE_TO_TOP_SIDE, + Screen::GetInstance().GetWidth() - VIEW_DISTANCE_TO_LEFT_SIDE, + 100); // 100: height + uiViewGroupFrame->SetStyle(STYLE_BORDER_COLOR, Color::White().full); + uiViewGroupFrame->SetStyle(STYLE_BORDER_OPA, HALF_OPA_OPAQUE); + uiViewGroupFrame->SetStyle(STYLE_BORDER_WIDTH, VIEW_STYLE_BORDER_WIDTH); + uiViewGroupFrame->SetStyle(STYLE_BORDER_RADIUS, VIEW_STYLE_BORDER_RADIUS); + uiViewGroupFrame->SetStyle(STYLE_BACKGROUND_OPA, 0); + uiViewGroupFrame->Add(gTarget_); + + gTarget_->SetPosition(0, 0, Screen::GetInstance().GetWidth() - VIEW_DISTANCE_TO_LEFT_SIDE, 100); // 100: height + uiViewGroup->Add(gridController_); + gridController_->SetPosition(0, 160, Screen::GetInstance().GetWidth(), 150); // 160: y-coordinate; 150: height + gridController_->SetLayoutDirection(LAYOUT_HOR); + gridController_->SetRows(3); // 3: row + gridController_->SetCols(4); // 4: col + + SetUpButton(gridController_, resetgBtn_, "reset"); + SetUpButton(gridController_, margingBtn_, "matgin"); + SetUpButton(gridController_, horgBtn_, "hor"); + SetUpButton(gridController_, horgRBtn_, "hor_r"); + SetUpButton(gridController_, vergBtn_, "ver"); + SetUpButton(gridController_, vergRBtn_, "ver_r"); + SetUpButton(gridController_, addElegBtn_, "add"); + SetUpButton(gridController_, incRowsBtn_, "incrows"); + SetUpButton(gridController_, decRowsBtn_, "decrows"); + SetUpButton(gridController_, incColsBtn_, "inccols"); + SetUpButton(gridController_, decColsBtn_, "deccols"); + SetUpButton(gridController_, layoutChildrengBtn_, "布局"); + gridController_->LayoutChildren(); + } +} + +void UITestAdvancedLayout::OnClickButton(const UIView& view) +{ + if (&view == resetgBtn_) { + Clear(gTarget_); + gTarget_->SetLayoutDirection(LAYOUT_HOR); + rows_ = 0; + cols_ = 0; + gTarget_->SetRows(rows_); + gTarget_->SetCols(cols_); + withMargin_ = false; + } else if (&view == margingBtn_) { + withMargin_ = true; + } else if (&view == horgBtn_) { + gTarget_->SetLayoutDirection(LAYOUT_HOR); + } else if (&view == horgRBtn_) { + gTarget_->SetLayoutDirection(LAYOUT_HOR_R); + } else if (&view == vergBtn_) { + gTarget_->SetLayoutDirection(LAYOUT_VER); + } else if (&view == vergRBtn_) { + gTarget_->SetLayoutDirection(LAYOUT_VER_R); + } else if (&view == addElegBtn_) { + AddElement(gTarget_); + } else if (&view == incRowsBtn_) { + rows_++; + gTarget_->SetRows(rows_); + } else if (&view == decRowsBtn_) { + rows_--; + gTarget_->SetRows(rows_); + } else if (&view == incColsBtn_) { + cols_++; + gTarget_->SetCols(cols_); + } else if (&view == decColsBtn_) { + cols_--; + gTarget_->SetCols(cols_); + } else if (&view == layoutChildrenfBtn_) { + fTarget_->LayoutChildren(); + fTarget_->Invalidate(); + } else if (&view == layoutChildrengBtn_) { + gTarget_->LayoutChildren(); + gTarget_->Invalidate(); + } else { + } +} + +bool UITestAdvancedLayout::OnClick(UIView& view, const ClickEvent& event) +{ + fTarget_->Invalidate(); + gTarget_->Invalidate(); + if (&view == resetfBtn_) { + Clear(fTarget_); + fTarget_->SetFlexWrap(false); + fTarget_->SetLayoutDirection(LAYOUT_HOR); + fTarget_->SetMajorAxisAlign(ALIGN_START); + fTarget_->SetSecondaryAxisAlign(ALIGN_CENTER); + withMargin_ = false; + } else if (&view == marginfBtn_) { + withMargin_ = true; + } else if (&view == horfBtn_) { + fTarget_->SetLayoutDirection(LAYOUT_HOR); + } else if (&view == horfRBtn_) { + fTarget_->SetLayoutDirection(LAYOUT_HOR_R); + } else if (&view == verfBtn_) { + fTarget_->SetLayoutDirection(LAYOUT_VER); + } else if (&view == verfRBtn_) { + fTarget_->SetLayoutDirection(LAYOUT_VER_R); + } else if (&view == wrapBtn_) { + fTarget_->SetFlexWrap(true); + } else if (&view == addElefBtn_) { + AddElement(fTarget_); + } else if (&view == majorStartBtn_) { + fTarget_->SetMajorAxisAlign(ALIGN_START); + } else if (&view == majorEndBtn_) { + fTarget_->SetMajorAxisAlign(ALIGN_END); + } else if (&view == majorCenterBtn_) { + fTarget_->SetMajorAxisAlign(ALIGN_CENTER); + } else if (&view == majorEvenBtn_) { + fTarget_->SetMajorAxisAlign(ALIGN_EVENLY); + } else if (&view == majorAroundBtn_) { + fTarget_->SetMajorAxisAlign(ALIGN_AROUND); + } else if (&view == majorBetBtn_) { + fTarget_->SetMajorAxisAlign(ALIGN_BETWEEN); + } else if (&view == secStartBtn_) { + fTarget_->SetSecondaryAxisAlign(ALIGN_START); + } else if (&view == secEndBtn_) { + fTarget_->SetSecondaryAxisAlign(ALIGN_CENTER); + } else if (&view == secCenterBtn_) { + fTarget_->SetMajorAxisAlign(ALIGN_END); + } else { + OnClickButton(view); + } + return true; +} +} // namespace OHOS \ No newline at end of file diff --git a/test/uitest/test_layout/ui_test_advanced_layout.h b/test/uitest/test_layout/ui_test_advanced_layout.h new file mode 100755 index 0000000..b67a7bb --- /dev/null +++ b/test/uitest/test_layout/ui_test_advanced_layout.h @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef UI_TEST_ADVANCED_LAYOUT_H +#define UI_TEST_ADVANCED_LAYOUT_H + +#include "components/ui_label.h" +#include "components/ui_label_button.h" +#include "components/ui_scroll_view.h" +#include "layout/flex_layout.h" +#include "layout/grid_layout.h" +#include "ui_test.h" + +namespace OHOS { +class UITestAdvancedLayout : public UITest, public UIView::OnClickListener { +public: + UITestAdvancedLayout() : withMargin_(false) {} + ~UITestAdvancedLayout() {} + void SetUp() override; + void TearDown() override; + UIView* GetTestView() override; + + /** + * @brief Test flex layout function. + */ + void UIKit_Layout_Test_FlexLayout_001(); + /** + * @brief Test grid layout function. + */ + void UIKit_Layout_Test_GridLayout_001(); + + bool OnClick(UIView& view, const ClickEvent& event) override; + void OnClickButton(const UIView& view); +private: + UIScrollView* container_ = nullptr; + GridLayout* flexController_ = nullptr; + GridLayout* gridController_ = nullptr; + FlexLayout* fTarget_ = nullptr; + GridLayout* gTarget_ = nullptr; + + UILabelButton* resetfBtn_ = nullptr; + UILabelButton* horfBtn_ = nullptr; + UILabelButton* horfRBtn_ = nullptr; + UILabelButton* verfBtn_ = nullptr; + UILabelButton* verfRBtn_ = nullptr; + UILabelButton* wrapBtn_ = nullptr; + UILabelButton* addElefBtn_ = nullptr; + UILabelButton* majorStartBtn_ = nullptr; + UILabelButton* majorEndBtn_ = nullptr; + UILabelButton* majorCenterBtn_ = nullptr; + UILabelButton* majorEvenBtn_ = nullptr; + UILabelButton* majorAroundBtn_ = nullptr; + UILabelButton* majorBetBtn_ = nullptr; + UILabelButton* secStartBtn_ = nullptr; + UILabelButton* secEndBtn_ = nullptr; + UILabelButton* secCenterBtn_ = nullptr; + UILabelButton* secInvalidBtn_ = nullptr; + UILabelButton* marginfBtn_ = nullptr; + UILabelButton* layoutChildrenfBtn_ = nullptr; + UILabelButton* horgBtn_ = nullptr; + UILabelButton* horgRBtn_ = nullptr; + UILabelButton* vergBtn_ = nullptr; + UILabelButton* vergRBtn_ = nullptr; + UILabelButton* incRowsBtn_ = nullptr; + UILabelButton* decRowsBtn_ = nullptr; + UILabelButton* incColsBtn_ = nullptr; + UILabelButton* decColsBtn_ = nullptr; + UILabelButton* addElegBtn_ = nullptr; + UILabelButton* resetgBtn_ = nullptr; + UILabelButton* margingBtn_ = nullptr; + UILabelButton* layoutChildrengBtn_ = nullptr; + + int16_t w_ = 10; // 10: width + int16_t h_ = 10; // 10: height + int16_t rows_ = 0; + int16_t cols_ = 0; + bool withMargin_; + + void SetUpButton(Layout* controller, UILabelButton* btn, const char* title) + { + controller->Add(btn); + btn->Resize(BUTTON_WIDHT2, BUTTON_HEIGHT2); + btn->SetText(title); + btn->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); + btn->SetOnClickListener(this); + btn->SetStyleForState(STYLE_BORDER_RADIUS, BUTTON_STYLE_BORDER_RADIUS_VALUE, UIButton::RELEASED); + btn->SetStyleForState(STYLE_BORDER_RADIUS, BUTTON_STYLE_BORDER_RADIUS_VALUE, UIButton::PRESSED); + btn->SetStyleForState(STYLE_BORDER_RADIUS, BUTTON_STYLE_BORDER_RADIUS_VALUE, UIButton::INACTIVE); + btn->SetStyleForState(STYLE_BACKGROUND_COLOR, BUTTON_STYLE_BACKGROUND_COLOR_VALUE, UIButton::RELEASED); + btn->SetStyleForState(STYLE_BACKGROUND_COLOR, BUTTON_STYLE_BACKGROUND_COLOR_VALUE, UIButton::PRESSED); + btn->SetStyleForState(STYLE_BACKGROUND_COLOR, BUTTON_STYLE_BACKGROUND_COLOR_VALUE, UIButton::INACTIVE); + } + void AddElement(Layout* layout) + { + UIView* view = new UIView(); + view->SetStyle(STYLE_BACKGROUND_COLOR, Color::Red().full); + view->Resize(w_++, h_++); + if (withMargin_) { + view->SetStyle(STYLE_MARGIN_LEFT, 10); // 10: margin left + view->SetStyle(STYLE_MARGIN_RIGHT, 15); // 15: margin right + view->SetStyle(STYLE_MARGIN_TOP, 20); // 20: margin top + view->SetStyle(STYLE_MARGIN_BOTTOM, 25); // 25: margin bottom + } + layout->Add(view); + } + void Clear(Layout* layout) const + { + if (layout == nullptr) { + return; + } + UIView* child = layout->GetChildrenHead(); + while (child != nullptr) { + UIView* temp = child; + child = child->GetNextSibling(); + layout->Remove(temp); + delete temp; + } + } +}; +} // namespace OHOS +#endif // UI_TEST_INPUT_EVENT_H diff --git a/test/uitest/test_layout/ui_test_basic_layout.cpp b/test/uitest/test_layout/ui_test_basic_layout.cpp new file mode 100755 index 0000000..42d1a59 --- /dev/null +++ b/test/uitest/test_layout/ui_test_basic_layout.cpp @@ -0,0 +1,249 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "ui_test_basic_layout.h" +#include "common/screen.h" + +namespace OHOS { +namespace { +const int16_t ITEM_H = 50; +const int16_t TEXT_H = 20; +const int16_t TEXT_W = 250; +const int16_t TEST_VIEW_H = 40; +const int16_t TEST_VIEW_W = 40; +const int16_t GAP = 5; +const int16_t TEST_VIEW_GAP = 80; +} // namespace + +void UITestBasicLayout::SetUp() +{ + container_ = new UIScrollView(); + layout_ = new GridLayout(); + uiViewGroupFrame_ = new UIViewGroup(); + testTarget_ = new UIViewGroup(); + testTargetSmall1_ = new UIView(); + testTargetSmall2_ = new UIView(); + refTarget_ = new UIView(); + resetBtn_ = new UILabelButton(); + marginBtn_ = new UILabelButton(); + padBtn_ = new UILabelButton(); + + lCenterOfParentBtn_ = new UILabelButton(); + lLeftOfParentBtn_ = new UILabelButton(); + lRightOfParentBtn_ = new UILabelButton(); + lTopOfParentBtn_ = new UILabelButton(); + lBottomOfParentBtn_ = new UILabelButton(); + + aLeftToSiblingBtn_ = new UILabelButton(); + aRightToSiblingBtn_ = new UILabelButton(); + aTopToSiblingBtn_ = new UILabelButton(); + aBottomToSiblingBtn_ = new UILabelButton(); + aHorCenterToSiblingBtn_ = new UILabelButton(); + aVerCenterToSiblingBtn_ = new UILabelButton(); + + lLeftToSiblingBtn_ = new UILabelButton(); + lRightToSiblingBtn_ = new UILabelButton(); + lTopToSiblingBtn_ = new UILabelButton(); + lBottomToSiblingBtn_ = new UILabelButton(); + lInvalidLayoutBtn_ = new UILabelButton(); + container_->Resize(Screen::GetInstance().GetWidth(), Screen::GetInstance().GetHeight() - BACK_BUTTON_HEIGHT); +} + +void UITestBasicLayout::TearDown() +{ + DeleteChildren(container_); + container_ = nullptr; + layout_ = nullptr; + testTarget_ = nullptr; + uiViewGroupFrame_ = nullptr; + testTargetSmall1_ = nullptr; + testTargetSmall2_ = nullptr; + refTarget_ = nullptr; + resetBtn_ = nullptr; + lCenterOfParentBtn_ = nullptr; + lLeftOfParentBtn_ = nullptr; + lRightOfParentBtn_ = nullptr; + lTopOfParentBtn_ = nullptr; + lBottomOfParentBtn_ = nullptr; + aLeftToSiblingBtn_ = nullptr; + aRightToSiblingBtn_ = nullptr; + aTopToSiblingBtn_ = nullptr; + aBottomToSiblingBtn_ = nullptr; + aHorCenterToSiblingBtn_ = nullptr; + aVerCenterToSiblingBtn_ = nullptr; + lLeftToSiblingBtn_ = nullptr; + lRightToSiblingBtn_ = nullptr; + lTopToSiblingBtn_ = nullptr; + lBottomToSiblingBtn_ = nullptr; + lInvalidLayoutBtn_ = nullptr; + marginBtn_ = nullptr; + padBtn_ = nullptr; + setStyle_ = nullptr; + positionX_ = 20; // 20: position x + positionY_ = 5; // 5 position y +} + +UIView* UITestBasicLayout::GetTestView() +{ + UIKit_Layout_Test_Basic_Layout_001(); + return container_; +} + +void UITestBasicLayout::UIKit_Layout_Test_Basic_Layout_001() +{ + if (container_ != nullptr) { + UIViewGroup* uiViewGroup = new UIViewGroup(); + uiViewGroup->SetPosition(0, 0, 320, 390); // 320: width; 390: height + container_->Add(uiViewGroup); + UILabel* label = new UILabel(); + uiViewGroup->Add(label); + label->SetPosition(TEXT_DISTANCE_TO_LEFT_SIDE, TEXT_DISTANCE_TO_TOP_SIDE, 288, 48); // 288: width; 48: height + label->SetText("布局效果"); + label->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); + uiViewGroup->Add(uiViewGroupFrame_); + // 288: width; 336: height + uiViewGroupFrame_->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE2, VIEW_DISTANCE_TO_TOP_SIDE, 288, 336); + uiViewGroupFrame_->SetStyle(STYLE_BORDER_COLOR, Color::White().full); + uiViewGroupFrame_->SetStyle(STYLE_BORDER_OPA, HALF_OPA_OPAQUE); + uiViewGroupFrame_->SetStyle(STYLE_BORDER_WIDTH, VIEW_STYLE_BORDER_WIDTH); + uiViewGroupFrame_->SetStyle(STYLE_BORDER_RADIUS, VIEW_STYLE_BORDER_RADIUS); + uiViewGroupFrame_->SetStyle(STYLE_BACKGROUND_OPA, 0); + uiViewGroupFrame_->Add(testTarget_); + testTarget_->SetPosition(0, 0, 96, 96); // 96: width 96:height + testTargetSmall1_->Resize(40, 40); // 40:width 40:height + testTargetSmall2_->Resize(20, 20); // 20:width 20:height + testTargetSmall1_->LayoutCenterOfParent(); + testTargetSmall2_->LayoutCenterOfParent(); + testTargetSmall1_->SetStyle(STYLE_BACKGROUND_COLOR, Color::Purple().full); + testTargetSmall2_->SetStyle(STYLE_BACKGROUND_COLOR, Color::Cyan().full); + testTarget_->SetStyle(STYLE_BACKGROUND_COLOR, Color::GetColorFromRGB(0, 182, 191).full); // 182, 191: color + uiViewGroupFrame_->Add(refTarget_); + refTarget_->Resize(VIEW_DISTANCE_TO_LEFT_SIDE, VIEW_DISTANCE_TO_TOP_SIDE); + refTarget_->SetViewId("refView"); + refTarget_->LayoutCenterOfParent(); + refTarget_->SetStyle(STYLE_BACKGROUND_COLOR, Color::GetColorFromRGB(255, 152, 0).full); // 255, 152: color + + UIViewGroup* uiViewGroup2 = new UIViewGroup(); + uiViewGroup2->SetPosition(336, 0, 600, 384); // 336: x-coordinate; 600: width; 384: height + container_->Add(uiViewGroup2); + UILabel* label2 = new UILabel(); + uiViewGroup2->Add(label2); + // 288: width; 48: height + label2->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE2, TEXT_DISTANCE_TO_TOP_SIDE, 288, 48); + label2->SetText("布局效果"); + label2->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); + uiViewGroup2->Add(layout_); + layout_->SetPosition(0, VIEW_DISTANCE_TO_TOP_SIDE, 516, 296); // 516: width; 296: height + layout_->SetLayoutDirection(LAYOUT_HOR); + layout_->SetRows(5); // 5: row + layout_->SetCols(4); // 4: col + InitSetUpButton(); + layout_->LayoutChildren(); + positionY_ += ITEM_H; + } +} + +void UITestBasicLayout::InitSetUpButton() +{ + SetUpButton(resetBtn_, "重置"); + SetUpButton(marginBtn_, "margin"); + SetUpButton(padBtn_, "padding"); + SetUpButton(lCenterOfParentBtn_, "居中"); + SetUpButton(lLeftOfParentBtn_, "居左"); + SetUpButton(lRightOfParentBtn_, "居右"); + SetUpButton(lTopOfParentBtn_, "居上"); + SetUpButton(lBottomOfParentBtn_, "居下"); + SetUpButton(aLeftToSiblingBtn_, "左侧对齐兄弟"); + SetUpButton(aRightToSiblingBtn_, "右侧对齐兄弟"); + SetUpButton(aTopToSiblingBtn_, "上侧对齐兄弟"); + SetUpButton(aBottomToSiblingBtn_, "下侧对齐兄弟"); + SetUpButton(aHorCenterToSiblingBtn_, "水平居中对齐"); + SetUpButton(aVerCenterToSiblingBtn_, "竖直居中对齐"); + SetUpButton(lLeftToSiblingBtn_, "放至兄弟左侧"); + SetUpButton(lRightToSiblingBtn_, "放至兄弟右侧"); + SetUpButton(lTopToSiblingBtn_, "放至兄弟上侧"); + SetUpButton(lBottomToSiblingBtn_, "放至兄弟下侧"); + SetUpButton(lInvalidLayoutBtn_, "非法节点布局"); +} + +void UITestBasicLayout::OnClickButton(UIView& view) +{ + if (&view == aLeftToSiblingBtn_) { + testTarget_->AlignLeftToSibling("refView"); + } else if (&view == aRightToSiblingBtn_) { + testTarget_->AlignRightToSibling("refView"); + } else if (&view == aTopToSiblingBtn_) { + testTarget_->AlignTopToSibling("refView"); + } else if (&view == aBottomToSiblingBtn_) { + testTarget_->AlignBottomToSibling("refView"); + } else if (&view == aHorCenterToSiblingBtn_) { + testTarget_->AlignHorCenterToSibling("refView"); + } else if (&view == aVerCenterToSiblingBtn_) { + testTarget_->AlignVerCenterToSibling("refView"); + } else if (&view == lLeftToSiblingBtn_) { + testTarget_->LayoutLeftToSibling("refView"); + } else if (&view == lRightToSiblingBtn_) { + testTarget_->LayoutRightToSibling("refView"); + } else if (&view == lTopToSiblingBtn_) { + testTarget_->LayoutTopToSibling("refView"); + } else if (&view == lBottomToSiblingBtn_) { + testTarget_->LayoutBottomToSibling("refView"); + } else if (&view == lInvalidLayoutBtn_) { + testTarget_->AlignLeftToSibling("invalid"); + } else { + } +} + +bool UITestBasicLayout::OnClick(UIView& view, const ClickEvent& event) +{ + uiViewGroupFrame_->Invalidate(); + if (&view == resetBtn_) { + testTarget_->SetPosition(0, 0); + testTarget_->SetStyle(STYLE_MARGIN_LEFT, 0); + testTarget_->SetStyle(STYLE_MARGIN_RIGHT, 0); + testTarget_->SetStyle(STYLE_MARGIN_TOP, 0); + testTarget_->SetStyle(STYLE_MARGIN_BOTTOM, 0); + uiViewGroupFrame_->SetStyle(STYLE_PADDING_LEFT, 0); + uiViewGroupFrame_->SetStyle(STYLE_PADDING_RIGHT, 0); + uiViewGroupFrame_->SetStyle(STYLE_PADDING_TOP, 0); + uiViewGroupFrame_->SetStyle(STYLE_PADDING_BOTTOM, 0); + } else if (&view == marginBtn_) { + testTarget_->SetStyle(STYLE_MARGIN_LEFT, 10); // 10: margin left + testTarget_->SetStyle(STYLE_MARGIN_RIGHT, 10); // 10: margin right + testTarget_->SetStyle(STYLE_MARGIN_TOP, 10); // 10: margin top + testTarget_->SetStyle(STYLE_MARGIN_BOTTOM, 10); // 10: margin bottom + } else if (&view == padBtn_) { + uiViewGroupFrame_->SetStyle(STYLE_PADDING_LEFT, 15); // 15: padding left + uiViewGroupFrame_->SetStyle(STYLE_PADDING_RIGHT, 15); // 15: padding right + uiViewGroupFrame_->SetStyle(STYLE_PADDING_TOP, 15); // 15: padding top + uiViewGroupFrame_->SetStyle(STYLE_PADDING_BOTTOM, 15); // 15: padding bottom + refTarget_->LayoutCenterOfParent(); + } else if (&view == lCenterOfParentBtn_) { + testTarget_->LayoutCenterOfParent(); + } else if (&view == lLeftOfParentBtn_) { + testTarget_->LayoutLeftOfParent(); + } else if (&view == lRightOfParentBtn_) { + testTarget_->LayoutRightOfParent(); + } else if (&view == lTopOfParentBtn_) { + testTarget_->LayoutTopOfParent(); + } else if (&view == lBottomOfParentBtn_) { + testTarget_->LayoutBottomOfParent(); + } else { + OnClickButton(view); + } + uiViewGroupFrame_->Invalidate(); + return true; +} +} // namespace OHOS \ No newline at end of file diff --git a/test/uitest/test_layout/ui_test_basic_layout.h b/test/uitest/test_layout/ui_test_basic_layout.h new file mode 100755 index 0000000..d22e1d9 --- /dev/null +++ b/test/uitest/test_layout/ui_test_basic_layout.h @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef UI_TEST_BASIC_LAYOUT_H +#define UI_TEST_BASIC_LAYOUT_H + +#include "components/ui_label.h" +#include "components/ui_label_button.h" +#include "components/ui_scroll_view.h" +#include "layout/flex_layout.h" +#include "layout/grid_layout.h" +#include "ui_test.h" + +namespace OHOS { +class UITestBasicLayout : public UITest, public UIView::OnClickListener { +public: + UITestBasicLayout() {} + ~UITestBasicLayout() {} + void SetUp() override; + void TearDown() override; + UIView* GetTestView() override; + + /** + * @brief Test basic layout function. + */ + void UIKit_Layout_Test_Basic_Layout_001(); + + bool OnClick(UIView& view, const ClickEvent& event) override; + void OnClickButton(UIView& view); + void InitSetUpButton(); +private: + UIScrollView* container_ = nullptr; + GridLayout* layout_ = nullptr; + UIViewGroup* uiViewGroupFrame_ = nullptr; + UIViewGroup* testTarget_ = nullptr; + UIView* testTargetSmall1_ = nullptr; + UIView* testTargetSmall2_ = nullptr; + UIView* refTarget_ = nullptr; + UILabelButton* resetBtn_ = nullptr; + + UILabelButton* lCenterOfParentBtn_ = nullptr; + UILabelButton* lLeftOfParentBtn_ = nullptr; + UILabelButton* lRightOfParentBtn_ = nullptr; + UILabelButton* lTopOfParentBtn_ = nullptr; + UILabelButton* lBottomOfParentBtn_ = nullptr; + + UILabelButton* aLeftToSiblingBtn_ = nullptr; + UILabelButton* aRightToSiblingBtn_ = nullptr; + UILabelButton* aTopToSiblingBtn_ = nullptr; + UILabelButton* aBottomToSiblingBtn_ = nullptr; + UILabelButton* aHorCenterToSiblingBtn_ = nullptr; + UILabelButton* aVerCenterToSiblingBtn_ = nullptr; + + UILabelButton* lLeftToSiblingBtn_ = nullptr; + UILabelButton* lRightToSiblingBtn_ = nullptr; + UILabelButton* lTopToSiblingBtn_ = nullptr; + UILabelButton* lBottomToSiblingBtn_ = nullptr; + UILabelButton* lInvalidLayoutBtn_ = nullptr; + UILabelButton* marginBtn_ = nullptr; + UILabelButton* padBtn_ = nullptr; + UILabelButton* setStyle_ = nullptr; + + void SetUpButton(UILabelButton* btn, const char* title) + { + if (btn == nullptr) { + return; + } + layout_->Add(btn); + btn->Resize(BUTTON_WIDHT2, BUTTON_HEIGHT2); + btn->SetText(title); + btn->SetFont(DEFAULT_VECTOR_FONT_FILENAME, BUTTON_LABEL_SIZE); + btn->SetOnClickListener(this); + btn->SetStyleForState(STYLE_BORDER_RADIUS, BUTTON_STYLE_BORDER_RADIUS_VALUE, UIButton::RELEASED); + btn->SetStyleForState(STYLE_BORDER_RADIUS, BUTTON_STYLE_BORDER_RADIUS_VALUE, UIButton::PRESSED); + btn->SetStyleForState(STYLE_BORDER_RADIUS, BUTTON_STYLE_BORDER_RADIUS_VALUE, UIButton::INACTIVE); + btn->SetStyleForState(STYLE_BACKGROUND_COLOR, BUTTON_STYLE_BACKGROUND_COLOR_VALUE, UIButton::RELEASED); + btn->SetStyleForState(STYLE_BACKGROUND_COLOR, BUTTON_STYLE_BACKGROUND_COLOR_VALUE, UIButton::PRESSED); + btn->SetStyleForState(STYLE_BACKGROUND_COLOR, BUTTON_STYLE_BACKGROUND_COLOR_VALUE, UIButton::INACTIVE); + } +}; +} // namespace OHOS +#endif // UI_TEST_INPUT_EVENT_H diff --git a/test/uitest/test_opacity/ui_test_opacity.cpp b/test/uitest/test_opacity/ui_test_opacity.cpp new file mode 100755 index 0000000..650a0e0 --- /dev/null +++ b/test/uitest/test_opacity/ui_test_opacity.cpp @@ -0,0 +1,492 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "ui_test_opacity.h" +#include "common/screen.h" +#include "components/ui_swipe_view.h" +#include "font/ui_font.h" +#include "test_resource_config.h" + +namespace OHOS { +namespace { +const int16_t TITLE_HEIGHT = 20; +const uint16_t LABEL_WIDTH = 200; +const uint16_t LABEL_HEIGHT = 50; +const uint16_t BUTTON_WIDTH = 150; +const uint16_t BUTTON_HEIGHT = 160; +const uint16_t CENTER_X = 100; +const uint16_t CENTER_Y = 100; +const uint16_t RADIUS = 80; +static ImageAnimatorInfo g_imageAnimatorInfo[4] = { + {GREEN_IMAGE_PATH, {50, 50}, 94, 94, IMG_SRC_FILE_PATH}, + {YELLOW_IMAGE_PATH, {50, 50}, 94, 94, IMG_SRC_FILE_PATH}, + {BLUE_IMAGE_PATH, {50, 50}, 94, 94, IMG_SRC_FILE_PATH}, + {RED_IMAGE_PATH, {50, 50}, 94, 94, IMG_SRC_FILE_PATH}, +}; +static ImageAnimatorInfo g_imageAnimatorInfo2[4] = { + {GREEN_IMAGE_PATH, {200, 50}, 94, 94, IMG_SRC_FILE_PATH}, + {YELLOW_IMAGE_PATH, {200, 50}, 94, 94, IMG_SRC_FILE_PATH}, + {BLUE_IMAGE_PATH, {200, 50}, 94, 94, IMG_SRC_FILE_PATH}, + {RED_IMAGE_PATH, {200, 50}, 94, 94, IMG_SRC_FILE_PATH}, +}; +} // namespace + +void UITestOpacity::SetUp() +{ + if (container_ == nullptr) { + container_ = new UIScrollView(); + container_->SetThrowDrag(true); + container_->Resize(Screen::GetInstance().GetWidth(), Screen::GetInstance().GetHeight() - BACK_BUTTON_HEIGHT); + } +} + +void UITestOpacity::TearDown() +{ + DeleteChildren(container_); + container_ = nullptr; +} + +UIViewGroup* UITestOpacity::CreateTestCaseGroup(const char* title) const +{ + UIViewGroup* group = new UIViewGroup(); + group->SetStyle(STYLE_BACKGROUND_COLOR, Color::Black().full); + group->SetStyle(STYLE_BACKGROUND_OPA, OPA_OPAQUE); + group->SetPosition(0, 0); + UILabel* titleLabel = new UILabel(); + titleLabel->SetPosition(0, 0, Screen::GetInstance().GetWidth(), TITLE_LABEL_DEFAULT_HEIGHT); + titleLabel->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); + titleLabel->SetText(title); + group->Add(titleLabel); + return group; +} + +const UIView* UITestOpacity::GetTestView() +{ + UIKitOpacityTestUILabel001(); + UIKitOpacityTestUILabel002(); + UIKitOpacityTestUIButton001(); + UIKitOpacityTestUIButton002(); + UIKitOpacityTestUILabelButton001(); + UIKitOpacityTestUIArcLabel001(); + UIKitOpacityTestUIImageView001(); + UIKitOpacityTestUIImageAnimator001(); + UIKitOpacityTestUIView001(); + UIKitOpacityTestUIViewGroup001(); + UIKitOpacityTestUIList001(); + UIKitOpacityTestUIScrollView001(); + UIKitOpacityTestUISwipeView001(); + return container_; +} + +UILabel* UITestOpacity::CreateTestCaseUILabel(const char* title, uint8_t opaScale) const +{ + UILabel* label = new UILabel(); + label->SetStyle(STYLE_BACKGROUND_COLOR, Color::Red().full); + label->SetStyle(STYLE_BACKGROUND_OPA, OPA_OPAQUE); + label->SetPosition(10, 30); // 10 width 30: height + label->Resize(LABEL_WIDTH, LABEL_HEIGHT); + label->SetFont(DEFAULT_VECTOR_FONT_FILENAME, 20); // 20:font size + label->SetText(title); + label->SetOpaScale(opaScale); // 200: opacity + return label; +} + +void UITestOpacity::UIKitOpacityTestUILabel001() +{ + if (container_ != nullptr) { + UIViewGroup* group = CreateTestCaseGroup(" display dynamic text with opacity 200 and 100"); + group->Resize(Screen::GetInstance().GetWidth(), LABEL_HEIGHT + 50); // 50 : height + group->SetViewId("UIKitOpacityTestUILabel001"); + UILabel* label = CreateTestCaseUILabel("轻量级GUI-200", 200); // 200: opacity + UILabel* label2 = CreateTestCaseUILabel("轻量级GUI-100", 100); // 100: opacity + label2->SetX(220); // 220: width + group->Add(label); + group->Add(label2); + container_->Add(group); + } +} + +void UITestOpacity::UIKitOpacityTestUILabel002() +{ + if (container_ != nullptr) { + UIViewGroup* group = CreateTestCaseGroup(" display dynamic text with opacity 256 and -1, uint8_t"); + group->Resize(Screen::GetInstance().GetWidth(), LABEL_HEIGHT + 50); // 50 : height + group->SetViewId("UIKitOpacityTestUILabel002"); + UILabel* label = CreateTestCaseUILabel("轻量级GUI-200", 256); // 256: opacity + UILabel* label2 = CreateTestCaseUILabel("轻量级GUI-100", -1); // -1: opacity + label2->SetX(220); // 220: width + group->Add(label); + group->Add(label2); + container_->Add(group); + group->LayoutBottomToSibling("UIKitOpacityTestUILabel001", 10); // 10: height + } +} + +void UITestOpacity::UIKitOpacityTestUIButton001() +{ + if (container_ != nullptr) { + UIViewGroup* group = CreateTestCaseGroup(" display UIButton with opacity 200 and 100"); + group->Resize(Screen::GetInstance().GetWidth(), BUTTON_HEIGHT); + group->SetViewId("UIKitOpacityTestUIButton001"); + + UIButton* button = new UIButton(); + button->SetPosition(10, 30, BUTTON_WIDTH, BUTTON_HEIGHT >> 1); // 10: width 30 :height + button->SetOpaScale(200); // 200: opacity + UIButton* button2 = new UIButton(); + button2->SetPosition(200, 30, BUTTON_WIDTH, BUTTON_HEIGHT >> 1); // 200: width 30 : height + button2->SetOpaScale(100); // 100: opacity + + group->Add(button); + group->Add(button2); + container_->Add(group); + group->LayoutBottomToSibling("UIKitOpacityTestUILabel002", 10); // 10: height + } +} + +UIButton* UITestOpacity::CreateTestCaseUIButton(uint8_t opaScale) const +{ + UIButton* button = new UIButton(); + button->SetStyle(STYLE_BACKGROUND_COLOR, Color::Red().full); + button->SetStyle(STYLE_BACKGROUND_OPA, OPA_OPAQUE); + button->SetPosition(10, 30, BUTTON_WIDTH, BUTTON_HEIGHT); // 10 30 x y + button->SetImageSrc(BLUE_IMAGE_PATH, YELLOW_IMAGE_PATH); + button->SetOpaScale(opaScale); // 200: opacity + return button; +} + +void UITestOpacity::UIKitOpacityTestUIButton002() +{ + if (container_ != nullptr) { + UIViewGroup* group = CreateTestCaseGroup(" display UIButton Image with opacity 200 and 100"); + group->Resize(Screen::GetInstance().GetWidth(), BUTTON_HEIGHT + 50); // 50 : height + group->SetViewId("UIKitOpacityTestUIButton002"); + + UIButton* button = CreateTestCaseUIButton(200); // 200: opacity + group->Add(button); + UIButton* button2 = CreateTestCaseUIButton(100); // 100: opacity + button2->SetPosition(200, 30); // 200: width 30 y + group->Add(button2); + container_->Add(group); + group->LayoutBottomToSibling("UIKitOpacityTestUIButton001", 10); // 10: height + } +} + +UILabelButton* UITestOpacity::CreateTestCaseUILabelButton(const char* title, uint8_t opaScale) const +{ + UILabelButton* labelButton = new UILabelButton(); + labelButton->SetPosition(10, 30, BUTTON_WIDTH, BUTTON_HEIGHT >> 1); // 10 x 30 : y + labelButton->SetText(title); + labelButton->SetOpaScale(opaScale); + return labelButton; +} + +void UITestOpacity::UIKitOpacityTestUILabelButton001() +{ + if (container_ != nullptr) { + UIViewGroup* group = CreateTestCaseGroup(" display UILabelButton with opacity 200 and 100"); + group->Resize(Screen::GetInstance().GetWidth(), BUTTON_HEIGHT); + group->SetViewId("UIKitOpacityTestUILabelButton001"); + UILabelButton* labelButton = CreateTestCaseUILabelButton("200", 200); // 200 : opacity + group->Add(labelButton); + UILabelButton* labelButton2 = CreateTestCaseUILabelButton("100", 100); // 100: opacity + labelButton2->SetX(200); // 200: width + group->Add(labelButton2); + container_->Add(group); + group->LayoutBottomToSibling("UIKitOpacityTestUIButton002", 10); // 10: height + } +} + +UIArcLabel* UITestOpacity::CreateTestCaseUIArcLabel(const char* title, uint8_t opaScale) const +{ + UIArcLabel* label = new UIArcLabel(); + label->SetArcTextCenter(CENTER_X, CENTER_Y + 20); // 20 : height + label->SetArcTextRadius(RADIUS); + label->SetArcTextAngle(270, 0); // 270: start angle, 0: end angle + label->SetFont(DEFAULT_VECTOR_FONT_FILENAME, 30); // 30: font size + label->SetStyle(STYLE_BACKGROUND_COLOR, Color::Red().full); + label->SetStyle(STYLE_BACKGROUND_OPA, OPA_OPAQUE); + label->SetText(title); + label->SetStyle(STYLE_LETTER_SPACE, 30); // 30: space + label->SetOpaScale(opaScale); // 200: opacity + return label; +} +void UITestOpacity::UIKitOpacityTestUIArcLabel001() +{ + if (container_ != nullptr) { + UIViewGroup* group = CreateTestCaseGroup(" display UIArcLabel with opacity 200 and 100"); + group->Resize(Screen::GetInstance().GetWidth(), BUTTON_HEIGHT + 50); // 50 : height + group->SetViewId("UIKitOpacityTestUIArcLabel001"); + UIArcLabel* label = CreateTestCaseUIArcLabel("01234567", 200); // 200: opacity + group->Add(label); + UIArcLabel* label2 = CreateTestCaseUIArcLabel("01234567", 100); // 100: opacity + if (label2 == nullptr) { + return; + } + label2->SetArcTextCenter(CENTER_X + 200, CENTER_Y + 20); // 200: width 20 : height + group->Add(label2); + container_->Add(group); + group->LayoutBottomToSibling("UIKitOpacityTestUILabelButton001", 10); // 10 : height + } +} + +UIImageView* UITestOpacity::CreateTestCaseUIImageView(const char* path, uint8_t opaScale) const +{ + UIImageView* imageView = new UIImageView(); + imageView->SetPosition(10, 30, 130, 130); // 10 x 30: y 130 : size + imageView->SetStyle(STYLE_BACKGROUND_COLOR, Color::Red().full); + imageView->SetStyle(STYLE_BACKGROUND_OPA, OPA_OPAQUE); + imageView->SetSrc(path); + imageView->SetOpaScale(opaScale); // 200: opacity + return imageView; +} + +void UITestOpacity::UIKitOpacityTestUIImageView001() +{ + if (container_ != nullptr) { + UIViewGroup* group = CreateTestCaseGroup(" display UIImageView with opacity 200 and 100"); + group->Resize(Screen::GetInstance().GetWidth(), BUTTON_HEIGHT + 50); // 50 : height + group->SetViewId("UIKitOpacityTestUIImageView001"); + UIImageView* imageView = CreateTestCaseUIImageView(BLUE_IMAGE_PATH, 200); // 200: opacity + group->Add(imageView); + UIImageView* imageView2 = CreateTestCaseUIImageView(BLUE_ARGB8888_IMAGE_PATH, 100); // 100: opacity + imageView2->SetX(200); // 200: width + group->Add(imageView2); + container_->Add(group); + group->LayoutBottomToSibling("UIKitOpacityTestUIArcLabel001", 10); // 10 : height + } +} + +UIImageAnimatorView* UITestOpacity::CreateTestCaseUIImageAnimator(const ImageAnimatorInfo imageAnimatorInfo[], + uint8_t opaScale) const +{ + UIImageAnimatorView* imageAnimator = new UIImageAnimatorView(); + imageAnimator->SetPosition(10, 30, 200, 200); // 10 : offset 30 : offset 200 : offset 200: offset + imageAnimator->SetOpaScale(opaScale); + imageAnimator->SetImageAnimatorSrc(imageAnimatorInfo, 4, 10); // 4: image number, 10: updating time + imageAnimator->Start(); + return imageAnimator; +} + +void UITestOpacity::UIKitOpacityTestUIImageAnimator001() +{ + if (container_ != nullptr) { + UIViewGroup* group = CreateTestCaseGroup(" display UIImageAnimator with opacity 200 and 100"); + group->Resize(Screen::GetInstance().GetWidth(), BUTTON_HEIGHT + 50); // 50: height + group->SetViewId("UIKitOpacityTestUIImageAnimator001"); + UIImageAnimatorView* imageAnimator = CreateTestCaseUIImageAnimator(g_imageAnimatorInfo, 200); // 200: opacity + group->Add(imageAnimator); + UIImageAnimatorView* imageAnimator2 = CreateTestCaseUIImageAnimator(g_imageAnimatorInfo2, 100); // 100: opacity + imageAnimator2->SetPosition(230, 30); // 230: width 30: height + group->Add(imageAnimator2); + container_->Add(group); + group->LayoutBottomToSibling("UIKitOpacityTestUIImageView001", 10); // 10: height + } +} +UIView* UITestOpacity::CreateTestCaseUIView(uint8_t opaScale) const +{ + UIView* view = new UIView(); + view->SetPosition(10, 30, BUTTON_WIDTH, BUTTON_HEIGHT); // 10: x 30: y + view->SetStyle(STYLE_BACKGROUND_COLOR, (Color::White()).full); + view->SetStyle(STYLE_BACKGROUND_OPA, OPA_OPAQUE); + view->SetOpaScale(opaScale); + return view; +} + +void UITestOpacity::UIKitOpacityTestUIView001() +{ + if (container_ != nullptr) { + UIViewGroup* group = CreateTestCaseGroup(" display UIView with opacity 200 and 100"); + group->Resize(Screen::GetInstance().GetWidth(), BUTTON_HEIGHT + 50); // 50 : height + group->SetViewId("UIKitOpacityTestUIView001"); + + UIView* view = CreateTestCaseUIView(200); // 200 : opacity + group->Add(view); + UIView* view2 = CreateTestCaseUIView(100); // 100 : opacity + view2->SetX(200); // 200: wdith + group->Add(view2); + + container_->Add(group); + group->LayoutBottomToSibling("UIKitOpacityTestUIImageAnimator001", 10); // 10 : height + } +} + +void UITestOpacity::UIKitOpacityTestUIViewGroup001() +{ + if (container_ != nullptr) { + UIViewGroup* group = CreateTestCaseGroup(" display UIViewGroup with opacity 200 and 100"); + group->Resize(Screen::GetInstance().GetWidth(), (BUTTON_HEIGHT << 1) + 100); // 100: height + group->SetViewId("UIKitOpacityTestUIViewGroup001"); + + UIViewGroup* group1 = new UIViewGroup(); + group1->SetPosition(10, 30, (BUTTON_WIDTH << 1) + 50, (BUTTON_HEIGHT << 1) + 100); // 30 y 50: width 100: height + group1->SetStyle(STYLE_BACKGROUND_COLOR, (Color::Red()).full); + UIViewGroup* group2 = new UIViewGroup(); + group2->SetPosition(170, 250, 150, 150); // 170: x 250: y 150: width 150: height + group2->SetStyle(STYLE_BACKGROUND_COLOR, (Color::White()).full); + + UILabelButton* labelButton = new UILabelButton(); + labelButton->SetPosition(10, 10, 60, 30); // 10: x y 60 wdith 30 height + labelButton->SetText("Test1"); + UILabelButton* labelButton2 = new UILabelButton(); + labelButton2->SetPosition(170, 10, 60, 30); // 170: x 10: y 60 wdith 30 height + labelButton2->SetText("Test2"); + labelButton2->SetOpaScale(100); // 100: opacity + UIButton* button = new UIButton(); + button->SetPosition(10, 60, BUTTON_WIDTH, BUTTON_HEIGHT); // 10: x 60: y + UIButton* button2 = new UIButton(); + button2->SetPosition(170, 60, BUTTON_WIDTH, BUTTON_HEIGHT); // 170: x 60: y + button2->SetImageSrc(BLUE_IMAGE_PATH, YELLOW_IMAGE_PATH); + button2->SetOpaScale(100); // 100: opacity + UIImageView* imageView = new UIImageView(); + imageView->SetPosition(10, 250, 50, 50); // 10: x 250: y 50 : size + imageView->SetSrc(BLUE_IMAGE_PATH); + imageView->SetOpaScale(100); // 100: opacity + UIImageView* imageView2 = new UIImageView(); + imageView2->SetPosition(10, 10, 50, 50); // 10: x y 50 : size + imageView2->SetSrc(YELLOW_IMAGE_PATH); + + group2->Add(imageView2); + group1->Add(labelButton); + group1->Add(labelButton2); + group1->Add(button); + group1->Add(button2); + group1->Add(imageView); + group1->Add(group2); + group2->SetOpaScale(100); // 100: opacity + group1->SetOpaScale(200); // 200: opacity + + group->Add(group1); + container_->Add(group); + group->LayoutBottomToSibling("UIKitOpacityTestUIView001", 10); // 10 : height + } +} + +UIList* UITestOpacity::CreateTestCaseUIList(uint8_t opaScale) const +{ + List* adapterData = new List(); + adapterData->PushBack("000"); + adapterData->PushBack("111"); + adapterData->PushBack("222"); + adapterData->PushBack("333"); + adapterData->PushBack("444"); + adapterData->PushBack("555"); + adapterData->PushBack("666"); + adapterData->PushBack("777"); + adapterData->PushBack("888"); + adapterData->PushBack("999"); + + TextAdapter* adapter = new TextAdapter(); + adapter->SetData(adapterData); + UIList* list = new UIList(UIList::VERTICAL); + list->SetStyle(STYLE_BACKGROUND_COLOR, Color::Red().full); + list->SetPosition(10, 30, BUTTON_WIDTH, BUTTON_HEIGHT); // 10 x 30 y + list->SetAdapter(adapter); + list->SetOpaScale(opaScale); // 200: opacity + return list; +} + +void UITestOpacity::UIKitOpacityTestUIList001() +{ + if (container_ != nullptr) { + UIViewGroup* group = CreateTestCaseGroup(" display UIList with opacity 200 and 100"); + group->Resize(Screen::GetInstance().GetWidth(), BUTTON_HEIGHT + 100); // 100: height + group->SetViewId("UIKitOpacityTestUIList001"); + UIList* list = CreateTestCaseUIList(200); // 200 : opacity + group->Add(list); + UIList* list2 = CreateTestCaseUIList(100); // 100 : opacity + list2->SetX(200); // 200: width + group->Add(list2); + container_->Add(group); + group->LayoutBottomToSibling("UIKitOpacityTestUIViewGroup001", 10); // 10 : height + } +} + +void UITestOpacity::UIKitOpacityTestUIScrollView001() +{ + if (container_ != nullptr) { + UIViewGroup* group = CreateTestCaseGroup(" display UIScrollView with opacity 200 and 100"); + group->Resize(Screen::GetInstance().GetWidth(), BUTTON_HEIGHT << 1); + group->SetViewId("UIKitOpacityTestUIScrollView001"); + + UIScrollView* group1 = new UIScrollView(); + group1->SetPosition(10, 30, (BUTTON_WIDTH << 1) + 50, (BUTTON_HEIGHT) + 100); // 10 x 30 y 50: width 100: height + group1->SetStyle(STYLE_BACKGROUND_COLOR, (Color::Red()).full); + UIScrollView* group2 = new UIScrollView(); + group2->SetPosition(170, 80, 150, 150); // 170: x 80: y 150: width 150: height + group2->SetStyle(STYLE_BACKGROUND_COLOR, (Color::White()).full); + UILabelButton* labelButton = new UILabelButton(); + labelButton->SetPosition(10, 10, 80, 40); // 10 x y 80: width 40: height + labelButton->SetText("test1"); + UILabelButton* labelButton2 = new UILabelButton(); + labelButton2->SetPosition(170, 10, 80, 40); // 170: x 10: y 80: width 40: height + labelButton2->SetText("test2"); + labelButton2->SetOpaScale(100); // 100: opacity + UIImageView* imageView = new UIImageView(); + imageView->SetPosition(10, 80, 50, 50); // 10: x 80: y 50 : size + imageView->SetSrc(BLUE_IMAGE_PATH); + imageView->SetOpaScale(100); // 100: opacity + UIImageView* imageView2 = new UIImageView(); + imageView2->SetPosition(10, 10, 50, 50); // 10: x y 50 : size + imageView2->SetSrc(YELLOW_IMAGE_PATH); + + group2->Add(imageView2); + group1->Add(labelButton); + group1->Add(labelButton2); + group1->Add(imageView); + group1->Add(group2); + group2->SetOpaScale(100); // 100: opacity + group1->SetOpaScale(200); // 200: opacity + group->Add(group1); + container_->Add(group); + group->LayoutBottomToSibling("UIKitOpacityTestUIList001", 10); // 10 : height + } +} + +void UITestOpacity::UIKitOpacityTestUISwipeView001() +{ + if (container_ != nullptr) { + UIViewGroup* group = CreateTestCaseGroup(" display UISwipeView with opacity 200 and 100"); + group->Resize(Screen::GetInstance().GetWidth(), BUTTON_HEIGHT); + group->SetViewId("UIKitOpacityTestUISwipeView001"); + + UISwipeView* swipe = new UISwipeView(UISwipeView::HORIZONTAL); + swipe->SetStyle(STYLE_BACKGROUND_COLOR, Color::Red().full); + swipe->SetPosition(10, 30, BUTTON_WIDTH << 1, BUTTON_HEIGHT); // 10 30 size + swipe->SetBlankSize(50); // 50: is blank size + group->Add(swipe); + + UILabelButton* button1 = new UILabelButton(); + button1->SetPosition(0, 0, BUTTON_WIDTH, BUTTON_HEIGHT >> 1); + button1->SetText("button1"); + swipe->Add(button1); + + UILabelButton* button2 = new UILabelButton(); + button2->SetPosition(0, 0, BUTTON_WIDTH, BUTTON_HEIGHT >> 1); + button2->SetText("button2"); + button2->SetOpaScale(200); // 200: opacity + swipe->Add(button2); + + UILabelButton* button3 = new UILabelButton(); + button3->SetPosition(0, 0, BUTTON_WIDTH, BUTTON_HEIGHT >> 1); + button3->SetText("button3"); + button3->SetOpaScale(100); // 100: opacity + swipe->Add(button3); + + swipe->SetOpaScale(200); // 200: opacity + container_->Add(group); + group->LayoutBottomToSibling("UIKitOpacityTestUIScrollView001", 10); // 10 : height + } +} +} // namespace OHOS diff --git a/test/uitest/test_opacity/ui_test_opacity.h b/test/uitest/test_opacity/ui_test_opacity.h new file mode 100755 index 0000000..4ba66a8 --- /dev/null +++ b/test/uitest/test_opacity/ui_test_opacity.h @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef UI_TEST_OPACITY_H +#define UI_TEST_OPACITY_H + +#include "components/root_view.h" +#include "components/text_adapter.h" +#include "components/ui_arc_label.h" +#include "components/ui_button.h" +#include "components/ui_image_animator.h" +#include "components/ui_image_view.h" +#include "components/ui_label.h" +#include "components/ui_label_button.h" +#include "components/ui_list.h" +#include "components/ui_scroll_view.h" +#include "ui_test.h" +namespace OHOS { +class UITestOpacity : public UITest { +public: + UITestOpacity() {} + ~UITestOpacity() {} + void SetUp() override; + void TearDown() override; + const UIView* GetTestView() override; + + /** + * @brief Test UILabel + */ + void UIKitOpacityTestUILabel001(); + + /** + * @brief Test UILabel exception value + */ + void UIKitOpacityTestUILabel002(); + + /** + * @brief Test UIButton + */ + void UIKitOpacityTestUIButton001(); + + /** + * @brief Test UIButton image + */ + void UIKitOpacityTestUIButton002(); + + /** + * @brief Test UILabelButton + */ + void UIKitOpacityTestUILabelButton001(); + + /** + * @brief Test UIArcLabel + */ + void UIKitOpacityTestUIArcLabel001(); + + /** + * @brief Test UIImageView + */ + void UIKitOpacityTestUIImageView001(); + + /** + * @brief Test UIImageAnimator + */ + void UIKitOpacityTestUIImageAnimator001(); + + /** + * @brief Test UIView + */ + void UIKitOpacityTestUIView001(); + + /** + * @brief Test UIViewGroup + */ + void UIKitOpacityTestUIViewGroup001(); + + /** + * @brief Test UIList + */ + void UIKitOpacityTestUIList001(); + + /** + * @brief Test UIScrollView + */ + void UIKitOpacityTestUIScrollView001(); + + /** + * @brief Test UISwipeView + */ + void UIKitOpacityTestUISwipeView001(); + +private: + UIViewGroup* CreateTestCaseGroup(const char* title) const; + UILabel* CreateTestCaseUILabel(const char* title, uint8_t opaScale) const; + UIButton* CreateTestCaseUIButton(uint8_t opaScale) const; + UILabelButton* CreateTestCaseUILabelButton(const char* title, uint8_t opaScale) const; + UIArcLabel* CreateTestCaseUIArcLabel(const char* title, uint8_t opaScale) const; + UIImageView* CreateTestCaseUIImageView(const char* path, uint8_t opaScale) const; + UIImageAnimatorView* CreateTestCaseUIImageAnimator(const ImageAnimatorInfo imageAnimatorInfo[], + uint8_t opaScale) const; + UIView* CreateTestCaseUIView(uint8_t opaScale) const; + UIList* CreateTestCaseUIList(uint8_t opaScale) const; + + UIScrollView* container_ = nullptr; +}; +} +#endif // UI_TEST_OPACITY_H diff --git a/test/uitest/test_picker/ui_test_ui_picker.cpp b/test/uitest/test_picker/ui_test_ui_picker.cpp new file mode 100755 index 0000000..4c95151 --- /dev/null +++ b/test/uitest/test_picker/ui_test_ui_picker.cpp @@ -0,0 +1,249 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "ui_test_ui_picker.h" +#include "common/screen.h" +#include "components/ui_label.h" +#include "components/ui_label_button.h" + +#include + +namespace OHOS { +namespace { +static int16_t g_ButtonH = 80; +static int16_t g_ButtonW = 200; +static int16_t g_blank = 38; +static int16_t g_ListW = 200; +static int16_t g_ListH = 300; +static const char* g_pickerRange[] = {"A0", "B1", "C2", "D3", "E4", "F5", "G6", "H7", "I8", "J9", "K10", "L11"}; +} // namespace + +void UITestUIPicker::SetUp() +{ + if (container_ == nullptr) { + container_ = new UIScrollView(); + container_->Resize(Screen::GetInstance().GetWidth(), Screen::GetInstance().GetHeight() - BACK_BUTTON_HEIGHT); + container_->SetThrowDrag(true); + container_->SetHorizontalScrollState(false); + } +} + +void UITestUIPicker::TearDown() +{ + container_->Remove(setLoopBtn_); + container_->Remove(setLoopOffBtn_); + container_->Remove(setSelectBtn_); + container_->Remove(setLeftToRightBtn_); + container_->Remove(setRightToLeftBtn_); + container_->Remove(selectIndex_); + container_->Remove(selectTime_); + container_->Remove(picker1_); + container_->Remove(picker2_); + container_->Remove(picker3_); + DeleteChildren(container_); + setLoopBtn_ = nullptr; + setLoopOffBtn_ = nullptr; + setSelectBtn_ = nullptr; + setLeftToRightBtn_ = nullptr; + setRightToLeftBtn_ = nullptr; + selectIndex_ = nullptr; + selectTime_ = nullptr; + container_ = nullptr; + picker1_ = nullptr; + picker2_ = nullptr; + picker3_ = nullptr; + + lastX_ = 0; + lastY_ = 0; +} + +UIView* UITestUIPicker::GetTestView() +{ + UIKit_Picker_Test_Base_001(); + UIKit_Picker_Test_Base_002(); + UIKit_Picker_Test_Time_Picker_001(); + return container_; +} + +void UITestUIPicker::OnPickerStoped(UIPicker& picker) +{ + uint16_t index = picker.GetSelected(); + selectIndex_->SetText(std::to_string(index).c_str()); + selectIndex_->Invalidate(); +} + +void UITestUIPicker::OnTimePickerStoped(UITimePicker& picker) +{ + selectTime_->SetText(picker.GetSelectValue()); + selectTime_->Invalidate(); +} + +void UITestUIPicker::UIKit_Picker_Test_Base_001() +{ + if (container_ == nullptr) { + return; + } + positionX_ = VIEW_DISTANCE_TO_LEFT_SIDE2; + UILabel* label = GetTitleLabel("UIPicker动态字体 "); + container_->Add(label); + label->SetPosition(positionX_, 0); + if (picker1_ == nullptr) { + picker1_ = new UIPicker(); + } + picker1_->SetPosition(positionX_, label->GetY() + g_blank, g_ListW, g_ListH); + picker1_->SetStyle(STYLE_BACKGROUND_OPA, OPA_OPAQUE); + picker1_->SetStyle(STYLE_BACKGROUND_COLOR, Color::Green().full); + picker1_->SetFontId(16, 18); // 16:back font id 18:high light font id + picker1_->SetItemHeight(50); // 50: height + picker1_->SetTextColor(Color::Gray(), Color::Red()); + picker1_->SetDirect(UITextLanguageDirect::TEXT_DIRECT_RTL); + picker1_->SetValues(g_pickerRange, sizeof(g_pickerRange) / sizeof(g_pickerRange[0])); + picker1_->RegisterSelectedListener(this); + + positionX_ = picker1_->GetWidth(); + positionY_ = picker1_->GetY(); + CreatButtons(); + if (selectIndex_ == nullptr) { + selectIndex_ = new UILabel(); + } + selectIndex_ = GetTitleLabel("NULL"); + selectIndex_->SetPosition(positionX_ + 40, label->GetY() + g_blank); // 40: increase x-coordinate + positionY_ += label->GetY() + g_blank; + container_->Add(selectIndex_); + SetUpButton(setLoopBtn_, "开启循环 "); + SetUpButton(setLoopOffBtn_, "关闭循环 "); + SetUpButton(setSelectBtn_, "定位到第5个 "); + SetUpButton(setLeftToRightBtn_, "从左往右 "); + SetUpButton(setRightToLeftBtn_, "从右往左 "); + container_->Add(picker1_); + SetLastPos(picker1_); +} + +void UITestUIPicker::CreatButtons() +{ + if (setLoopBtn_ == nullptr) { + setLoopBtn_ = new UILabelButton(); + } + if (setLoopOffBtn_ == nullptr) { + setLoopOffBtn_ = new UILabelButton(); + } + if (setSelectBtn_ == nullptr) { + setSelectBtn_ = new UILabelButton(); + } + if (setLeftToRightBtn_ == nullptr) { + setLeftToRightBtn_ = new UILabelButton(); + } + if (setRightToLeftBtn_ == nullptr) { + setRightToLeftBtn_ = new UILabelButton(); + } +} + +void UITestUIPicker::UIKit_Picker_Test_Base_002() +{ + if (container_ == nullptr) { + return; + } + UILabel* label = GetTitleLabel("UIPicker区间数字 "); + container_->Add(label); + label->SetPosition(390, 0); // 390 x-coordinate + if (picker3_ == nullptr) { + picker3_ = new UIPicker(); + } + picker3_->SetPosition(390, g_blank, g_ListW, g_ListH); // 390: x-coordinate + picker3_->SetFontId(16, 18); // 16:back font id 18:high light font id + picker3_->SetItemHeight(50); // 50: height + picker3_->SetTextColor(Color::Gray(), Color::Red()); + picker3_->SetValues(-5, 20); // -5: start 20:end + picker3_->SetTextFormatter(new TextFormatter()); + + positionX_ = picker3_->GetWidth(); + positionY_ = picker3_->GetY(); + + container_->Add(picker3_); + SetLastPos(picker3_); +} + +void UITestUIPicker::UIKit_Picker_Test_Time_Picker_001() +{ + if (container_ == nullptr) { + return; + } + UILabel* label = GetTitleLabel("Time Picker"); + container_->Add(label); + label->SetPosition(672, 0); // 672: x-coordinate + label->SetStyle(STYLE_BACKGROUND_OPA, OPA_OPAQUE); + if (picker2_ == nullptr) { + picker2_ = new UITimePicker(); + } + picker2_->EnableSecond(true); + picker2_->SetPosition(652, label->GetY() + g_blank, g_ListW, g_ListH); // 652: x-coordinate + picker2_->SetItemHeight(50); // 50 height + picker2_->RegisterSelectedListener(this); + positionX_ = picker2_->GetWidth(); + positionY_ = picker2_->GetY(); + + if (selectTime_ == nullptr) { + selectTime_ = new UILabel(); + } + selectTime_ = GetTitleLabel("NULL"); + picker2_->RegisterSelectedListener(this); + selectTime_->SetPosition(662 + picker2_->GetWidth(), label->GetY() + g_blank); // 662: increase x-coordinate + container_->Add(selectTime_); + container_->Add(picker2_); + SetLastPos(picker2_); +} + +bool UITestUIPicker::OnClick(UIView& view, const ClickEvent& event) +{ + if (&view == setLoopBtn_) { + picker1_->SetLoopState(true); + } else if (&view == setLoopOffBtn_) { + picker1_->SetLoopState(false); + } else if (&view == setSelectBtn_) { + picker1_->SetSelected(5); // 5: index + } else if (&view == setLeftToRightBtn_) { + picker1_->SetDirect(UITextLanguageDirect::TEXT_DIRECT_LTR); + } else if (&view == setRightToLeftBtn_) { + picker1_->SetDirect(UITextLanguageDirect::TEXT_DIRECT_RTL); + } + return true; +} + +void UITestUIPicker::SetUpButton(UILabelButton* btn, const char* title) +{ + if (btn == nullptr) { + return; + } + container_->Add(btn); + btn->SetPosition(positionX_ + 30, positionY_, BUTTON_WIDHT2, BUTTON_HEIGHT2); // 30: increase x-coordinate; + positionY_ += btn->GetHeight() + 12; // 12: increase y-coordinate + btn->SetText(title); + btn->SetFont(DEFAULT_VECTOR_FONT_FILENAME, BUTTON_LABEL_SIZE); + btn->SetOnClickListener(this); + btn->SetStyleForState(STYLE_BORDER_RADIUS, BUTTON_STYLE_BORDER_RADIUS_VALUE, UIButton::RELEASED); + btn->SetStyleForState(STYLE_BORDER_RADIUS, BUTTON_STYLE_BORDER_RADIUS_VALUE, UIButton::PRESSED); + btn->SetStyleForState(STYLE_BORDER_RADIUS, BUTTON_STYLE_BORDER_RADIUS_VALUE, UIButton::INACTIVE); + btn->SetStyleForState(STYLE_BACKGROUND_COLOR, BUTTON_STYLE_BACKGROUND_COLOR_VALUE, UIButton::RELEASED); + btn->SetStyleForState(STYLE_BACKGROUND_COLOR, BUTTON_STYLE_BACKGROUND_COLOR_VALUE, UIButton::PRESSED); + btn->SetStyleForState(STYLE_BACKGROUND_COLOR, BUTTON_STYLE_BACKGROUND_COLOR_VALUE, UIButton::INACTIVE); + container_->Invalidate(); +} + +void UITestUIPicker::SetLastPos(UIView* view) +{ + lastX_ = view->GetX(); + lastY_ = view->GetY() + view->GetHeight(); +} +} // namespace OHOS diff --git a/test/uitest/test_picker/ui_test_ui_picker.h b/test/uitest/test_picker/ui_test_ui_picker.h new file mode 100755 index 0000000..0d3e9cc --- /dev/null +++ b/test/uitest/test_picker/ui_test_ui_picker.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef UI_TEST_UI_PICKER_H +#define UI_TEST_UI_PICKER_H + +#include "components/text_adapter.h" +#include "components/ui_label.h" +#include "components/ui_label_button.h" +#include "components/ui_picker.h" +#include "components/ui_scroll_view.h" +#include "components/ui_time_picker.h" +#include "ui_test.h" + +namespace OHOS { +class UITestUIPicker : public UITest, UIView::OnClickListener, UIPicker::SelectedListener, + UITimePicker::SelectedListener { +public: + UITestUIPicker() {} + ~UITestUIPicker() {} + void SetUp() override; + void TearDown() override; + bool OnClick(UIView& view, const ClickEvent& event) override; + UIView* GetTestView() override; + void OnPickerStoped(UIPicker& picker) override; + void OnTimePickerStoped(UITimePicker& picker) override; + void CreatButtons(); + void UIKit_Picker_Test_Base_001(); + void UIKit_Picker_Test_Base_002(); + void UIKit_Picker_Test_Time_Picker_001(); + +private: + void SetLastPos(UIView* view); + void SetUpButton(UILabelButton* btn, const char* title); + UILabelButton* setLoopBtn_ = nullptr; + UILabelButton* setLoopOffBtn_ = nullptr; + UILabelButton* setSelectBtn_ = nullptr; + UILabelButton* setLeftToRightBtn_ = nullptr; + UILabelButton* setRightToLeftBtn_ = nullptr; + UILabel* selectIndex_ = nullptr; + UILabel* selectTime_ = nullptr; + UIScrollView* container_ = nullptr; + UIPicker* picker1_ = nullptr; + UIPicker* picker3_ = nullptr; + UITimePicker* picker2_ = nullptr; + int16_t lastX_ = 0; + int16_t lastY_ = 0; +}; +} // namespace OHOS +#endif // UI_TEST_UI_PICKER_H diff --git a/test/uitest/test_progress_bar/ui_test_box_progress.cpp b/test/uitest/test_progress_bar/ui_test_box_progress.cpp new file mode 100755 index 0000000..c08b19d --- /dev/null +++ b/test/uitest/test_progress_bar/ui_test_box_progress.cpp @@ -0,0 +1,435 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "ui_test_box_progress.h" +#include "common/screen.h" +#include "components/ui_label.h" +#include "test_resource_config.h" + +namespace OHOS { +namespace { +const int16_t LABEL_HEIGHT = 29; +const int16_t BUTTON_WIDTH = 120; +const int16_t BUTTON_HEIGHT = 40; +const int16_t DELTA_X_COORDINATE = 8; +const int16_t DELTA_X_COORDINATE_2 = 336; +const int16_t DELTA_Y_COORDINATE = 12; +const int16_t DELTA_Y_COORDINATE_2 = 19; +} // namespace + +void UITestBoxProgress::SetUp() +{ + if (container_ == nullptr) { + positionX_ = 0; + positionY_ = 0; + container_ = new UIScrollView(); + container_->Resize(Screen::GetInstance().GetWidth(), Screen::GetInstance().GetHeight() - BACK_BUTTON_HEIGHT); + UIViewGroup* uiViewGroup = new UIViewGroup(); + uiViewGroup->SetPosition(positionX_, positionY_, 320, 390); // 320: width; 390: height + container_->Add(uiViewGroup); + UILabel* label = new UILabel(); + uiViewGroup->Add(label); + // 288: width; 48: height + label->SetPosition(TEXT_DISTANCE_TO_LEFT_SIDE, TEXT_DISTANCE_TO_TOP_SIDE, 288, 48); + label->SetText("UIBoxProgress效果"); + label->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); + uiViewGroupFrame_ = new UIViewGroup(); + uiViewGroup->Add(uiViewGroupFrame_); + // 288: width; 336: height + uiViewGroupFrame_->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE2, TEXT_DISTANCE_TO_LEFT_SIDE, 288, 336); + uiViewGroupFrame_->SetStyle(STYLE_BORDER_COLOR, Color::White().full); + uiViewGroupFrame_->SetStyle(STYLE_BORDER_OPA, HALF_OPA_OPAQUE); + uiViewGroupFrame_->SetStyle(STYLE_BORDER_WIDTH, VIEW_STYLE_BORDER_WIDTH); + uiViewGroupFrame_->SetStyle(STYLE_BORDER_RADIUS, VIEW_STYLE_BORDER_RADIUS); + uiViewGroupFrame_->SetStyle(STYLE_BACKGROUND_OPA, 0); + + boxProgress_ = new UIBoxProgress(); + boxProgress_->SetPosition(10, 10, 100, 10); // 10: x 10: y 100: width 10: height + boxProgress_->SetValue(20); // 20: value + boxProgress_->SetBackgroundStyle(STYLE_BACKGROUND_COLOR, Color::Red().full); + boxProgress_->SetForegroundStyle(STYLE_BACKGROUND_COLOR, Color::Green().full); + boxProgress_->SetStyle(STYLE_BORDER_COLOR, Color::Yellow().full); + uiViewGroupFrame_->Add(boxProgress_); + boxProgress_->LayoutCenterOfParent(); + } + + if (scroll_ == nullptr) { + scroll_ = new UIScrollView(); + scroll_->SetPosition(336, 11); // 336: x-coordinate; 11: y-coordinate + // 624: width; 100: Adjust the visible height of scroll + scroll_->Resize(624, Screen::GetInstance().GetHeight() - 100); + container_->Add(scroll_); + positionY_ = 0; + } +} + +void UITestBoxProgress::TearDown() +{ + DeleteChildren(container_); + container_ = nullptr; + boxProgress_ = nullptr; + scroll_ = nullptr; + uiViewGroupFrame_ = nullptr; +} + +UIView* UITestBoxProgress::GetTestView() +{ + UIKit_BoxProgress_Test_UIBoxProgress_001(); + UIKit_BoxProgress_Test_SetRange_002(); + UIKit_BoxProgress_Test_SetValue_003(); + UIKit_BoxProgress_Test_SetImage_004(); + UIKit_BoxProgress_Test_SetStyle_005(); + UIKit_BoxProgress_Test_GetStyle_006(); + UIKit_BoxProgress_Test_SetCapType_007(); + UIKit_BoxProgress_Test_SetDirection_008(); + UIKit_BoxProgress_Test_EnableBackground_009(); + UIKit_BoxProgress_Test_SetStep_010(); + UIKit_BoxProgress_Test_SetValidSize_011(); + UIKit_BoxProgress_Test_SetBorderAndPadding_012(); + + return container_; +} + +void UITestBoxProgress::SetUpLabel(const char* title, int16_t x, int16_t y) const +{ + UILabel* label = new UILabel(); + scroll_->Add(label); + label->SetPosition(x, y, 288, 30); // 288: width; 30: height + label->SetText(title); + label->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); +} +void UITestBoxProgress::SetUpButton(UILabelButton* btn, const char* title, int16_t x, int16_t y) +{ + if (btn == nullptr) { + return; + } + scroll_->Add(btn); + btn->SetPosition(x, y, BUTTON_WIDHT2, BUTTON_HEIGHT2); + btn->SetText(title); + btn->SetFont(DEFAULT_VECTOR_FONT_FILENAME, BUTTON_LABEL_SIZE); + btn->SetOnClickListener(this); + btn->SetStyleForState(STYLE_BORDER_RADIUS, BUTTON_STYLE_BORDER_RADIUS_VALUE, UIButton::RELEASED); + btn->SetStyleForState(STYLE_BORDER_RADIUS, BUTTON_STYLE_BORDER_RADIUS_VALUE, UIButton::PRESSED); + btn->SetStyleForState(STYLE_BORDER_RADIUS, BUTTON_STYLE_BORDER_RADIUS_VALUE, UIButton::INACTIVE); + btn->SetStyleForState(STYLE_BACKGROUND_COLOR, BUTTON_STYLE_BACKGROUND_COLOR_VALUE, UIButton::RELEASED); + btn->SetStyleForState(STYLE_BACKGROUND_COLOR, BUTTON_STYLE_BACKGROUND_COLOR_VALUE, UIButton::PRESSED); + btn->SetStyleForState(STYLE_BACKGROUND_COLOR, BUTTON_STYLE_BACKGROUND_COLOR_VALUE, UIButton::INACTIVE); + scroll_->Invalidate(); +} + +void UITestBoxProgress::UIKit_BoxProgress_Test_UIBoxProgress_001() +{ + resetBtn_ = new UILabelButton(); + positionX_ = VIEW_DISTANCE_TO_LEFT_SIDE2; + positionY_ = 0; + SetUpLabel("创建条形进度条:", positionX_, positionY_); + positionY_ += LABEL_HEIGHT + DELTA_X_COORDINATE; + SetUpButton(resetBtn_, "重置", positionX_, positionY_); +} + +void UITestBoxProgress::UIKit_BoxProgress_Test_SetRange_002() +{ + incMinProgressBtn_ = new UILabelButton(); + decMinProgressBtn_ = new UILabelButton(); + incMaxProgressBtn_ = new UILabelButton(); + decMaxProgressBtn_ = new UILabelButton(); + positionX_ = VIEW_DISTANCE_TO_LEFT_SIDE2; + positionY_ += BUTTON_HEIGHT + DELTA_Y_COORDINATE_2; + SetUpLabel("设置条形进度条范围:", positionX_, positionY_); + positionY_ += LABEL_HEIGHT + DELTA_X_COORDINATE; + SetUpButton(incMinProgressBtn_, "下限+", positionX_, positionY_); + positionX_ += BUTTON_WIDTH + DELTA_Y_COORDINATE; + SetUpButton(decMinProgressBtn_, "下限-", positionX_, positionY_); + positionX_ = VIEW_DISTANCE_TO_LEFT_SIDE2; + positionY_ += BUTTON_HEIGHT + DELTA_Y_COORDINATE; + SetUpButton(incMaxProgressBtn_, "上限+", positionX_, positionY_); + positionX_ += BUTTON_WIDTH + DELTA_Y_COORDINATE; + SetUpButton(decMaxProgressBtn_, "上限-", positionX_, positionY_); +} + +void UITestBoxProgress::UIKit_BoxProgress_Test_SetValue_003() +{ + incProgressBtn_ = new UILabelButton(); + decProgressBtn_ = new UILabelButton(); + positionX_ = VIEW_DISTANCE_TO_LEFT_SIDE2; + positionY_ += BUTTON_HEIGHT + DELTA_Y_COORDINATE_2; + SetUpLabel("设置条形进度条当前值:", positionX_, positionY_); + positionY_ += LABEL_HEIGHT + DELTA_X_COORDINATE; + SetUpButton(incProgressBtn_, "进度+", positionX_, positionY_); + positionX_ += BUTTON_WIDTH + DELTA_Y_COORDINATE; + SetUpButton(decProgressBtn_, "进度-", positionX_, positionY_); +} + +void UITestBoxProgress::UIKit_BoxProgress_Test_SetImage_004() +{ + imageBtn_ = new UILabelButton(); + noImageBtn_ = new UILabelButton(); + positionX_ = VIEW_DISTANCE_TO_LEFT_SIDE2; + positionY_ += BUTTON_HEIGHT + DELTA_Y_COORDINATE_2; + SetUpLabel("设置条形进度条图片:", positionX_, positionY_); + positionY_ += LABEL_HEIGHT + DELTA_X_COORDINATE; + SetUpButton(imageBtn_, "设置图片", positionX_, positionY_); + positionX_ += BUTTON_WIDTH + DELTA_Y_COORDINATE; + SetUpButton(noImageBtn_, "取消图片", positionX_, positionY_); +} + +void UITestBoxProgress::UIKit_BoxProgress_Test_SetStyle_005() +{ + setStyleBtn_ = new UILabelButton(); + positionX_ = VIEW_DISTANCE_TO_LEFT_SIDE2; + positionY_ += BUTTON_HEIGHT + DELTA_Y_COORDINATE_2; + SetUpLabel("设置条形进度条样式:", positionX_, positionY_); + positionY_ += LABEL_HEIGHT + DELTA_X_COORDINATE; + SetUpButton(setStyleBtn_, "设置样式", positionX_, positionY_); +} + +void UITestBoxProgress::UIKit_BoxProgress_Test_GetStyle_006() +{ + getStyleBtn_ = new UILabelButton(); + positionX_ = VIEW_DISTANCE_TO_LEFT_SIDE2; + positionY_ += BUTTON_HEIGHT + DELTA_Y_COORDINATE_2; + SetUpLabel("设置条形进度条样式:", positionX_, positionY_); + positionY_ += LABEL_HEIGHT + DELTA_X_COORDINATE; + SetUpButton(getStyleBtn_, "设置样式", positionX_, positionY_); +} + +void UITestBoxProgress::UIKit_BoxProgress_Test_SetCapType_007() +{ + roundCapBtn_ = new UILabelButton(); + noneCapBtn_ = new UILabelButton(); + positionX_ = DELTA_X_COORDINATE_2; + positionY_ = 0; + SetUpLabel("设置条形进度条端点:", positionX_, positionY_); + positionY_ += LABEL_HEIGHT + DELTA_X_COORDINATE; + SetUpButton(roundCapBtn_, "圆形端点", positionX_, positionY_); + positionX_ += BUTTON_WIDTH + DELTA_Y_COORDINATE; + SetUpButton(noneCapBtn_, "方形端点", positionX_, positionY_); +} + +void UITestBoxProgress::UIKit_BoxProgress_Test_SetDirection_008() +{ + dirL2RBtn_ = new UILabelButton(); + dirR2LBtn_ = new UILabelButton(); + dirT2BBtn_ = new UILabelButton(); + dirB2TBtn_ = new UILabelButton(); + positionX_ = DELTA_X_COORDINATE_2; + positionY_ += BUTTON_HEIGHT + DELTA_Y_COORDINATE_2; + SetUpLabel("设置条形进度条方向:", positionX_, positionY_); + positionY_ += LABEL_HEIGHT + DELTA_X_COORDINATE; + SetUpButton(dirL2RBtn_, "从左到右", positionX_, positionY_); + positionX_ += BUTTON_WIDTH + DELTA_Y_COORDINATE; + SetUpButton(dirR2LBtn_, "从右到左", positionX_, positionY_); + positionX_ = DELTA_X_COORDINATE_2; + positionY_ += BUTTON_HEIGHT + DELTA_Y_COORDINATE; + SetUpButton(dirT2BBtn_, "从上到下", positionX_, positionY_); + positionX_ += BUTTON_WIDTH + DELTA_Y_COORDINATE; + SetUpButton(dirB2TBtn_, "从下到上", positionX_, positionY_); +} + +void UITestBoxProgress::UIKit_BoxProgress_Test_EnableBackground_009() +{ + enableBgBtn_ = new UILabelButton(); + disableBgBtn_ = new UILabelButton(); + positionX_ = DELTA_X_COORDINATE_2; + positionY_ += BUTTON_HEIGHT + DELTA_Y_COORDINATE_2; + SetUpLabel("设置条形进度条背景:", positionX_, positionY_); + positionY_ += LABEL_HEIGHT + DELTA_X_COORDINATE; + SetUpButton(enableBgBtn_, "设置背景", positionX_, positionY_); + positionX_ += BUTTON_WIDTH + DELTA_Y_COORDINATE; + SetUpButton(disableBgBtn_, "隐藏背景", positionX_, positionY_); +} + +void UITestBoxProgress::UIKit_BoxProgress_Test_SetStep_010() +{ + stepBtn_ = new UILabelButton(); + positionX_ = DELTA_X_COORDINATE_2; + positionY_ += BUTTON_HEIGHT + DELTA_Y_COORDINATE_2; + SetUpLabel("设置条形进度条步长:", positionX_, positionY_); + positionY_ += LABEL_HEIGHT + DELTA_X_COORDINATE; + SetUpButton(stepBtn_, "步长+", positionX_, positionY_); +} + +void UITestBoxProgress::UIKit_BoxProgress_Test_SetValidSize_011() +{ + widthBtn_ = new UILabelButton(); + heightBtn_ = new UILabelButton(); + positionX_ = DELTA_X_COORDINATE_2; + positionY_ += BUTTON_HEIGHT + DELTA_Y_COORDINATE_2; + SetUpLabel("设置条形进度条有效区域宽高:", positionX_, positionY_); + positionY_ += LABEL_HEIGHT + DELTA_X_COORDINATE; + SetUpButton(heightBtn_, "box高度-", positionX_, positionY_); + positionX_ += BUTTON_WIDTH + DELTA_Y_COORDINATE; + SetUpButton(widthBtn_, "box宽度-", positionX_, positionY_); +} + +void UITestBoxProgress::UIKit_BoxProgress_Test_SetBorderAndPadding_012() +{ + borderIncBtn_ = new UILabelButton(); + borderDecBtn_ = new UILabelButton(); + paddingLeftIncBtn_ = new UILabelButton(); + paddingRightIncBtn_ = new UILabelButton(); + paddingTopIncBtn_ = new UILabelButton(); + paddingBottomIncBtn_ = new UILabelButton(); + positionX_ = DELTA_X_COORDINATE_2; + positionY_ += BUTTON_HEIGHT + DELTA_Y_COORDINATE_2; + SetUpLabel("设置边宽和内边距:", positionX_, positionY_); + positionY_ += LABEL_HEIGHT + DELTA_X_COORDINATE; + SetUpButton(borderIncBtn_, "边宽+", positionX_, positionY_); + positionX_ += BUTTON_WIDTH + DELTA_Y_COORDINATE_2; + SetUpButton(borderDecBtn_, "边宽-", positionX_, positionY_); + positionX_ = DELTA_X_COORDINATE_2; + positionY_ += BUTTON_HEIGHT + DELTA_Y_COORDINATE_2; + SetUpButton(paddingLeftIncBtn_, "左内边距+", positionX_, positionY_); + positionX_ += BUTTON_WIDTH + DELTA_Y_COORDINATE_2; + SetUpButton(paddingRightIncBtn_, "右内边距+", positionX_, positionY_); + positionX_ = DELTA_X_COORDINATE_2; + positionY_ += BUTTON_HEIGHT + DELTA_Y_COORDINATE_2; + SetUpButton(paddingTopIncBtn_, "上内边距+", positionX_, positionY_); + positionX_ += BUTTON_WIDTH + DELTA_Y_COORDINATE_2; + SetUpButton(paddingBottomIncBtn_, "下内边距+", positionX_, positionY_); +} + +bool UITestBoxProgress::OnClick(UIView& view, const ClickEvent& event) +{ + static uint16_t progress = 20; // 20: progress + static uint16_t step = 0; + static uint16_t width = 100; // 100: width + static uint16_t height = 10; // 10: height + static int16_t min = 0; + static int16_t max = 100; // 100: max value + if (&view == resetBtn_) { + boxProgress_->SetPosition(10, 10, 100, 10); // 10: x 10: y 100: width 15: height + progress = 20; // 20: progress + step = 0; + width = 100; // 100: width + height = 10; // 10: height + min = 0; + max = 100; // 100: max value + boxProgress_->SetDirection(UIBoxProgress::Direction::DIR_LEFT_TO_RIGHT); + boxProgress_->SetValidHeight(height); + boxProgress_->SetValidWidth(width); + boxProgress_->SetRange(max, min); + boxProgress_->SetValue(progress); + boxProgress_->SetStep(step); + // 182, 191: color + boxProgress_->SetBackgroundStyle(STYLE_BACKGROUND_COLOR, Color::GetColorFromRGB(0, 182, 191).full); + // 255, 152: color + boxProgress_->SetForegroundStyle(STYLE_BACKGROUND_COLOR, Color::GetColorFromRGB(255, 152, 0).full); + boxProgress_->SetImage(static_cast(nullptr)); + boxProgress_->EnableBackground(true); + boxProgress_->LayoutCenterOfParent(); + } else if (&view == incProgressBtn_) { + progress++; + boxProgress_->SetValue(progress); + } else if (&view == decProgressBtn_) { + progress--; + boxProgress_->SetValue(progress); + } else if (&view == stepBtn_) { + step++; + boxProgress_->SetStep(step); + } else if (&view == widthBtn_) { + width--; + boxProgress_->SetValidWidth(width); + } else if (&view == heightBtn_) { + height--; + boxProgress_->SetValidHeight(height); + } else if (&view == incMinProgressBtn_) { + min++; + boxProgress_->SetRange(boxProgress_->GetRangeMax(), min); + } else if (&view == decMinProgressBtn_) { + min--; + boxProgress_->SetRange(boxProgress_->GetRangeMax(), min); + } else if (&view == incMaxProgressBtn_) { + max++; + boxProgress_->SetRange(max, boxProgress_->GetRangeMin()); + } else if (&view == decMaxProgressBtn_) { + max--; + boxProgress_->SetRange(max, boxProgress_->GetRangeMin()); + } else if (&view == dirL2RBtn_) { + width = 100; // 100: width + height = 10; // 10: height + boxProgress_->Resize(width, height); + boxProgress_->SetDirection(UIBoxProgress::Direction::DIR_LEFT_TO_RIGHT); + } else if (&view == dirR2LBtn_) { + width = 100; // 100: width + height = 10; // 10: height + boxProgress_->Resize(width, height); + boxProgress_->SetDirection(UIBoxProgress::Direction::DIR_RIGHT_TO_LEFT); + } else if (&view == dirT2BBtn_) { + width = 10; // 10: width + height = 100; // 100: height + boxProgress_->Resize(width, height); + boxProgress_->SetDirection(UIBoxProgress::Direction::DIR_TOP_TO_BOTTOM); + } else if (&view == dirB2TBtn_) { + width = 10; // 10: width + height = 100; // 100: height + boxProgress_->Resize(width, height); + boxProgress_->SetDirection(UIBoxProgress::Direction::DIR_BOTTOM_TO_TOP); + } else if (&view == imageBtn_) { + boxProgress_->SetImage(RED_IMAGE_PATH, BLUE_IMAGE_PATH); + } else if (&view == noImageBtn_) { + boxProgress_->SetImage(static_cast(nullptr)); + } else if (&view == setStyleBtn_) { + Style style = StyleDefault::GetDefaultStyle(); + style.bgColor_ = Color::White(); + boxProgress_->SetBackgroundStyle(style); + style.bgColor_ = Color::Blue(); + boxProgress_->SetForegroundStyle(style); + } else if (&view == getStyleBtn_) { + boxProgress_->SetBackgroundStyle(STYLE_BACKGROUND_COLOR, Color::Red().full); + boxProgress_->SetForegroundStyle(STYLE_BACKGROUND_COLOR, Color::Yellow().full); + } else if (&view == roundCapBtn_) { + boxProgress_->SetCapType(CapType::CAP_ROUND); + } else if (&view == noneCapBtn_) { + boxProgress_->SetCapType(CapType::CAP_NONE); + } else if (&view == enableBgBtn_) { + boxProgress_->EnableBackground(true); + } else if (&view == disableBgBtn_) { + boxProgress_->EnableBackground(false); + } else if (&view == borderIncBtn_) { + int64_t bodrderWidth = boxProgress_->GetStyle(STYLE_BORDER_WIDTH); + // 20: max width; 5: step + bodrderWidth = (bodrderWidth + 5 > 20) ? 20 : (bodrderWidth + 5); + boxProgress_->SetStyle(STYLE_BORDER_WIDTH, bodrderWidth); + } else if (&view == borderDecBtn_) { + int64_t bodrderWidth = boxProgress_->GetStyle(STYLE_BORDER_WIDTH); + // 0: min width; 5: step + bodrderWidth = (bodrderWidth - 5 < 0) ? 0 : (bodrderWidth - 5); + boxProgress_->SetStyle(STYLE_BORDER_WIDTH, bodrderWidth); + } else if (&view == paddingLeftIncBtn_) { + int64_t paddingWidth = boxProgress_->GetStyle(STYLE_PADDING_LEFT); + // 20: max width; 5: step + paddingWidth = (paddingWidth + 5 > 20) ? 20 : (paddingWidth + 5); + boxProgress_->SetStyle(STYLE_PADDING_LEFT, paddingWidth); + } else if (&view == paddingRightIncBtn_) { + int64_t paddingWidth = boxProgress_->GetStyle(STYLE_PADDING_RIGHT); + // 20: max width; 5: step + paddingWidth = (paddingWidth + 5 > 20) ? 20 : (paddingWidth + 5); + boxProgress_->SetStyle(STYLE_PADDING_RIGHT, paddingWidth); + } else if (&view == paddingTopIncBtn_) { + int64_t paddingWidth = boxProgress_->GetStyle(STYLE_PADDING_TOP); + // 20: max width; 5: step + paddingWidth = (paddingWidth + 5 > 20) ? 20 : (paddingWidth + 5); + boxProgress_->SetStyle(STYLE_PADDING_TOP, paddingWidth); + } else if (&view == paddingBottomIncBtn_) { + int64_t paddingWidth = boxProgress_->GetStyle(STYLE_PADDING_BOTTOM); + // 20: max width; 5: step + paddingWidth = (paddingWidth + 5 > 20) ? 20 : (paddingWidth + 5); + boxProgress_->SetStyle(STYLE_PADDING_BOTTOM, paddingWidth); + } + container_->Invalidate(); + return true; +} +} // namespace OHOS \ No newline at end of file diff --git a/test/uitest/test_progress_bar/ui_test_box_progress.h b/test/uitest/test_progress_bar/ui_test_box_progress.h new file mode 100755 index 0000000..c4174d1 --- /dev/null +++ b/test/uitest/test_progress_bar/ui_test_box_progress.h @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef UI_TEST_BOX_PROGRESS_H +#define UI_TEST_BOX_PROGRESS_H + +#include "components/ui_box_progress.h" +#include "components/ui_label_button.h" +#include "components/ui_scroll_view.h" +#include "ui_test.h" + +namespace OHOS { +class UITestBoxProgress : public UITest, public UIView::OnClickListener { +public: + UITestBoxProgress() {} + ~UITestBoxProgress() {} + void SetUp() override; + void TearDown() override; + UIView* GetTestView() override; + + void SetUpButton(UILabelButton* btn, const char* title, int16_t x, int16_t y); + void SetUpLabel(const char* title, int16_t x, int16_t y) const; + + bool OnClick(UIView& view, const ClickEvent& event) override; + + void UIKit_BoxProgress_Test_UIBoxProgress_001(); + void UIKit_BoxProgress_Test_SetRange_002(); + void UIKit_BoxProgress_Test_SetValue_003(); + void UIKit_BoxProgress_Test_SetImage_004(); + void UIKit_BoxProgress_Test_SetStyle_005(); + void UIKit_BoxProgress_Test_GetStyle_006(); + void UIKit_BoxProgress_Test_SetCapType_007(); + void UIKit_BoxProgress_Test_SetDirection_008(); + void UIKit_BoxProgress_Test_EnableBackground_009(); + void UIKit_BoxProgress_Test_SetStep_010(); + void UIKit_BoxProgress_Test_SetValidSize_011(); + void UIKit_BoxProgress_Test_SetBorderAndPadding_012(); + +private: + UIScrollView* container_ = nullptr; + UIScrollView* scroll_ = nullptr; + UIBoxProgress* boxProgress_ = nullptr; + UIViewGroup* uiViewGroupFrame_ = nullptr; + + UILabelButton* resetBtn_ = nullptr; + UILabelButton* widthBtn_ = nullptr; + UILabelButton* heightBtn_ = nullptr; + UILabelButton* incProgressBtn_ = nullptr; + UILabelButton* decProgressBtn_ = nullptr; + UILabelButton* incMinProgressBtn_ = nullptr; + UILabelButton* decMinProgressBtn_ = nullptr; + UILabelButton* incMaxProgressBtn_ = nullptr; + UILabelButton* decMaxProgressBtn_ = nullptr; + UILabelButton* stepBtn_ = nullptr; + UILabelButton* dirL2RBtn_ = nullptr; + UILabelButton* dirR2LBtn_ = nullptr; + UILabelButton* dirT2BBtn_ = nullptr; + UILabelButton* dirB2TBtn_ = nullptr; + UILabelButton* imageBtn_ = nullptr; + UILabelButton* noImageBtn_ = nullptr; + UILabelButton* setStyleBtn_ = nullptr; + UILabelButton* getStyleBtn_ = nullptr; + UILabelButton* roundCapBtn_ = nullptr; + UILabelButton* noneCapBtn_ = nullptr; + UILabelButton* enableBgBtn_ = nullptr; + UILabelButton* disableBgBtn_ = nullptr; + UILabelButton* borderIncBtn_ = nullptr; + UILabelButton* borderDecBtn_ = nullptr; + UILabelButton* paddingLeftIncBtn_ = nullptr; + UILabelButton* paddingRightIncBtn_ = nullptr; + UILabelButton* paddingTopIncBtn_ = nullptr; + UILabelButton* paddingBottomIncBtn_ = nullptr; +}; +} // namespace OHOS +#endif // UI_TEST_BOX_PROGRESS_H diff --git a/test/uitest/test_progress_bar/ui_test_circle_progress.cpp b/test/uitest/test_progress_bar/ui_test_circle_progress.cpp new file mode 100755 index 0000000..d92343a --- /dev/null +++ b/test/uitest/test_progress_bar/ui_test_circle_progress.cpp @@ -0,0 +1,473 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "ui_test_circle_progress.h" +#include "common/screen.h" +#include "components/ui_label.h" +#include "test_resource_config.h" + +namespace OHOS { +namespace { +const int16_t LABEL_HEIGHT = 29; +const int16_t BUTTON_WIDTH = 120; +const int16_t BUTTON_HEIGHT = 40; +const int16_t DELTA_X_COORDINATE = 8; +const int16_t DELTA_X_COORDINATE_2 = 336; +const int16_t DELTA_Y_COORDINATE = 12; +const int16_t DELTA_Y_COORDINATE_2 = 19; +} // namespace + +void UITestCircleProgress::SetUp() +{ + if (container_ == nullptr) { + positionX_ = 0; + positionY_ = 0; + container_ = new UIScrollView(); + container_->Resize(Screen::GetInstance().GetWidth(), Screen::GetInstance().GetHeight() - BACK_BUTTON_HEIGHT); + UIViewGroup* uiViewGroup = new UIViewGroup(); + uiViewGroup->SetPosition(positionX_, positionY_, 320, 390); // 320: width; 390: height + container_->Add(uiViewGroup); + UILabel* label = new UILabel(); + uiViewGroup->Add(label); + // 288: x-coordinate; 48: y-coordinate + label->SetPosition(TEXT_DISTANCE_TO_LEFT_SIDE, TEXT_DISTANCE_TO_TOP_SIDE, 288, 48); + label->SetText("UICircleProgress效果"); + label->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); + uiViewGroupFrame_ = new UIViewGroup(); + uiViewGroup->Add(uiViewGroupFrame_); + // 288: width; 336: height + uiViewGroupFrame_->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE2, VIEW_DISTANCE_TO_TOP_SIDE, 288, 336); + uiViewGroupFrame_->SetStyle(STYLE_BORDER_COLOR, Color::White().full); + uiViewGroupFrame_->SetStyle(STYLE_BORDER_OPA, HALF_OPA_OPAQUE); + uiViewGroupFrame_->SetStyle(STYLE_BORDER_WIDTH, VIEW_STYLE_BORDER_WIDTH); + uiViewGroupFrame_->SetStyle(STYLE_BORDER_RADIUS, VIEW_STYLE_BORDER_RADIUS); + uiViewGroupFrame_->SetStyle(STYLE_BACKGROUND_OPA, 0); + + circleProgress_ = new UICircleProgress(); + circleProgress_->SetPosition(10, 10, 150, 150); // 10: x 10:y 150:width 150: height + circleProgress_->SetCenterPosition(75, 75); // 75: position x 75: position y + circleProgress_->SetRadius(50); // 50: radius + circleProgress_->SetValue(20); // 20: value + circleProgress_->SetStyle(STYLE_PADDING_LEFT, 10); // 10: value + circleProgress_->SetStyle(STYLE_PADDING_TOP, 5); // 5: value + uiViewGroupFrame_->Add(circleProgress_); + circleProgress_->LayoutCenterOfParent(); + } + + if (scroll_ == nullptr) { + scroll_ = new UIScrollView(); + scroll_->SetPosition(336, 11); // 336: x-coordinate; 11: y-coordinate + scroll_->Resize(624, container_->GetHeight() - 11); // 624: width; // 11: decrease height + container_->Add(scroll_); + positionY_ = 0; + } +} + +void UITestCircleProgress::TearDown() +{ + DeleteChildren(container_); + container_ = nullptr; + circleProgress_ = nullptr; + scroll_ = nullptr; +} + +UIView* UITestCircleProgress::GetTestView() +{ + UIKit_CircleProgress_Test_UICircleProgress_001(); + UIKit_CircleProgress_Test_SetValue_002(); + UIKit_CircleProgress_Test_SetImage_003(); + UIKit_CircleProgress_Test_SetStyle_004(); + UIKit_CircleProgress_Test_GetStyle_005(); + UIKit_CircleProgress_Test_SetCapType_006(); + UIKit_CircleProgress_Test_SetStep_007(); + UIKit_CircleProgress_Test_SetRange_008(); + UIKit_CircleProgress_Test_EnableBackground_009(); + UIKit_CircleProgress_Test_SetCenter_010(); + UIKit_CircleProgress_Test_SetRadius_011(); + UIKit_CircleProgress_Test_SetLineWidth_012(); + UIKit_CircleProgress_Test_SetImagePosition_013(); + UIKit_CircleProgress_Test_SetLineColor_014(); + UIKit_CircleProgress_Test_SetAngle_015(); + + return container_; +} + +void UITestCircleProgress::SetUpLabel(const char* title, int16_t x, int16_t y) const +{ + UILabel* label = new UILabel(); + scroll_->Add(label); + label->SetPosition(x, y, 288, 30); // 288: width; 30: height + label->SetText(title); + label->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); +} +void UITestCircleProgress::SetUpButton(UILabelButton* btn, const char* title, int16_t x, int16_t y) +{ + if (btn == nullptr) { + return; + } + scroll_->Add(btn); + btn->SetPosition(x, y, BUTTON_WIDHT2, BUTTON_HEIGHT2); + btn->SetText(title); + btn->SetFont(DEFAULT_VECTOR_FONT_FILENAME, BUTTON_LABEL_SIZE); + btn->SetOnClickListener(this); + btn->SetStyleForState(STYLE_BORDER_RADIUS, BUTTON_STYLE_BORDER_RADIUS_VALUE, UIButton::RELEASED); + btn->SetStyleForState(STYLE_BORDER_RADIUS, BUTTON_STYLE_BORDER_RADIUS_VALUE, UIButton::PRESSED); + btn->SetStyleForState(STYLE_BORDER_RADIUS, BUTTON_STYLE_BORDER_RADIUS_VALUE, UIButton::INACTIVE); + btn->SetStyleForState(STYLE_BACKGROUND_COLOR, BUTTON_STYLE_BACKGROUND_COLOR_VALUE, UIButton::RELEASED); + btn->SetStyleForState(STYLE_BACKGROUND_COLOR, BUTTON_STYLE_BACKGROUND_COLOR_VALUE, UIButton::PRESSED); + btn->SetStyleForState(STYLE_BACKGROUND_COLOR, BUTTON_STYLE_BACKGROUND_COLOR_VALUE, UIButton::INACTIVE); + scroll_->Invalidate(); +} + +void UITestCircleProgress::UIKit_CircleProgress_Test_UICircleProgress_001() +{ + resetBtn_ = new UILabelButton(); + positionX_ = VIEW_DISTANCE_TO_LEFT_SIDE2; + positionY_ = 0; + SetUpLabel("创建环形进度条:", positionX_, positionY_); + positionY_ += LABEL_HEIGHT + DELTA_X_COORDINATE; + SetUpButton(resetBtn_, "重置", positionX_, positionY_); +} + +void UITestCircleProgress::UIKit_CircleProgress_Test_SetRange_008() +{ + incMinProgressBtn_ = new UILabelButton(); + decMinProgressBtn_ = new UILabelButton(); + incMaxProgressBtn_ = new UILabelButton(); + decMaxProgressBtn_ = new UILabelButton(); + positionX_ = VIEW_DISTANCE_TO_LEFT_SIDE2; + positionY_ += BUTTON_HEIGHT + DELTA_Y_COORDINATE_2; + SetUpLabel("设置环形进度条范围:", positionX_, positionY_); + positionY_ += LABEL_HEIGHT + DELTA_X_COORDINATE; + SetUpButton(incMinProgressBtn_, "下限+", positionX_, positionY_); + positionX_ += BUTTON_WIDTH + DELTA_Y_COORDINATE; + SetUpButton(decMinProgressBtn_, "下限-", positionX_, positionY_); + positionX_ = VIEW_DISTANCE_TO_LEFT_SIDE2; + positionY_ += BUTTON_HEIGHT + DELTA_Y_COORDINATE; + SetUpButton(incMaxProgressBtn_, "上限+", positionX_, positionY_); + positionX_ += BUTTON_WIDTH + DELTA_Y_COORDINATE; + SetUpButton(decMaxProgressBtn_, "上限-", positionX_, positionY_); +} + +void UITestCircleProgress::UIKit_CircleProgress_Test_SetValue_002() +{ + incProgressBtn_ = new UILabelButton(); + decProgressBtn_ = new UILabelButton(); + positionX_ = VIEW_DISTANCE_TO_LEFT_SIDE2; + positionY_ += BUTTON_HEIGHT + DELTA_Y_COORDINATE_2; + SetUpLabel("设置环形进度条当前值:", positionX_, positionY_); + positionY_ += LABEL_HEIGHT + DELTA_X_COORDINATE; + SetUpButton(incProgressBtn_, "进度+", positionX_, positionY_); + positionX_ += BUTTON_WIDTH + DELTA_Y_COORDINATE; + SetUpButton(decProgressBtn_, "进度-", positionX_, positionY_); +} + +void UITestCircleProgress::UIKit_CircleProgress_Test_SetImage_003() +{ + imageBtn_ = new UILabelButton(); + noImageBtn_ = new UILabelButton(); + positionX_ = VIEW_DISTANCE_TO_LEFT_SIDE2; + positionY_ += BUTTON_HEIGHT + DELTA_Y_COORDINATE_2; + SetUpLabel("设置环形进度条图片:", positionX_, positionY_); + positionY_ += LABEL_HEIGHT + DELTA_X_COORDINATE; + SetUpButton(imageBtn_, "设置图片", positionX_, positionY_); + positionX_ += BUTTON_WIDTH + DELTA_Y_COORDINATE; + SetUpButton(noImageBtn_, "取消图片", positionX_, positionY_); +} + +void UITestCircleProgress::UIKit_CircleProgress_Test_SetStyle_004() +{ + setStyleBtn_ = new UILabelButton(); + positionX_ = VIEW_DISTANCE_TO_LEFT_SIDE2; + positionY_ += BUTTON_HEIGHT + DELTA_Y_COORDINATE_2; + SetUpLabel("设置环形进度条样式:", positionX_, positionY_); + positionY_ += LABEL_HEIGHT + DELTA_X_COORDINATE; + SetUpButton(setStyleBtn_, "设置样式", positionX_, positionY_); +} + +void UITestCircleProgress::UIKit_CircleProgress_Test_GetStyle_005() +{ + getStyleBtn_ = new UILabelButton(); + positionX_ = VIEW_DISTANCE_TO_LEFT_SIDE2; + positionY_ += BUTTON_HEIGHT + DELTA_Y_COORDINATE_2; + SetUpLabel("设置环形进度条样式:", positionX_, positionY_); + positionY_ += LABEL_HEIGHT + DELTA_X_COORDINATE; + SetUpButton(getStyleBtn_, "设置样式", positionX_, positionY_); +} + +void UITestCircleProgress::UIKit_CircleProgress_Test_SetCapType_006() +{ + roundCapBtn_ = new UILabelButton(); + noneCapBtn_ = new UILabelButton(); + positionX_ = VIEW_DISTANCE_TO_LEFT_SIDE2; + positionY_ += BUTTON_HEIGHT + DELTA_Y_COORDINATE_2; + SetUpLabel("设置环形进度条端点:", positionX_, positionY_); + positionY_ += LABEL_HEIGHT + DELTA_X_COORDINATE; + SetUpButton(roundCapBtn_, "圆形端点", positionX_, positionY_); + positionX_ += BUTTON_WIDTH + DELTA_Y_COORDINATE; + SetUpButton(noneCapBtn_, "方形端点", positionX_, positionY_); +} + +void UITestCircleProgress::UIKit_CircleProgress_Test_SetStep_007() +{ + stepBtn_ = new UILabelButton(); + positionX_ = VIEW_DISTANCE_TO_LEFT_SIDE2; + positionY_ += BUTTON_HEIGHT + DELTA_Y_COORDINATE_2; + SetUpLabel("设置环形进度条步长:", positionX_, positionY_); + positionY_ += LABEL_HEIGHT + DELTA_X_COORDINATE; + SetUpButton(stepBtn_, "步长+", positionX_, positionY_); +} + +void UITestCircleProgress::UIKit_CircleProgress_Test_EnableBackground_009() +{ + enableBgBtn_ = new UILabelButton(); + disableBgBtn_ = new UILabelButton(); + positionX_ = DELTA_X_COORDINATE_2; + positionY_ = 0; + SetUpLabel("环形进度条隐藏背景:", positionX_, positionY_); + positionY_ += LABEL_HEIGHT + DELTA_X_COORDINATE; + SetUpButton(enableBgBtn_, "设置背景", positionX_, positionY_); + positionX_ += BUTTON_WIDTH + DELTA_Y_COORDINATE; + SetUpButton(disableBgBtn_, "隐藏背景", positionX_, positionY_); +} + +void UITestCircleProgress::UIKit_CircleProgress_Test_SetCenter_010() +{ + centerXBtn_ = new UILabelButton(); + centerYBtn_ = new UILabelButton(); + positionX_ = DELTA_X_COORDINATE_2; + positionY_ += BUTTON_HEIGHT + DELTA_Y_COORDINATE_2; + SetUpLabel("设置环形进度条圆心:", positionX_, positionY_); + positionY_ += LABEL_HEIGHT + DELTA_X_COORDINATE; + SetUpButton(centerXBtn_, "圆心X+", positionX_, positionY_); + positionX_ += BUTTON_WIDTH + DELTA_Y_COORDINATE; + SetUpButton(centerYBtn_, "圆心Y+", positionX_, positionY_); +} + +void UITestCircleProgress::UIKit_CircleProgress_Test_SetRadius_011() +{ + incRadiusBtn_ = new UILabelButton(); + decRadiusBtn_ = new UILabelButton(); + positionX_ = DELTA_X_COORDINATE_2; + positionY_ += BUTTON_HEIGHT + DELTA_Y_COORDINATE_2; + SetUpLabel("设置环形进度条半径:", positionX_, positionY_); + positionY_ += LABEL_HEIGHT + DELTA_X_COORDINATE; + SetUpButton(incRadiusBtn_, "半径+", positionX_, positionY_); + positionX_ += BUTTON_WIDTH + DELTA_Y_COORDINATE; + SetUpButton(decRadiusBtn_, "半径-", positionX_, positionY_); +} + +void UITestCircleProgress::UIKit_CircleProgress_Test_SetLineWidth_012() +{ + incWidthBtn_ = new UILabelButton(); + decWidthBtn_ = new UILabelButton(); + positionX_ = DELTA_X_COORDINATE_2; + positionY_ += BUTTON_HEIGHT + DELTA_Y_COORDINATE_2; + SetUpLabel("设置环形进度条线宽:", positionX_, positionY_); + positionY_ += LABEL_HEIGHT + DELTA_X_COORDINATE; + SetUpButton(incWidthBtn_, "线宽+", positionX_, positionY_); + positionX_ += BUTTON_WIDTH + DELTA_Y_COORDINATE; + SetUpButton(decWidthBtn_, "线宽-", positionX_, positionY_); +} + +void UITestCircleProgress::UIKit_CircleProgress_Test_SetImagePosition_013() +{ + imgPosXBtn_ = new UILabelButton(); + imgPosYBtn_ = new UILabelButton(); + positionX_ = DELTA_X_COORDINATE_2; + positionY_ += BUTTON_HEIGHT + DELTA_Y_COORDINATE_2; + SetUpLabel("设置环形进度条图片位置:", positionX_, positionY_); + positionY_ += LABEL_HEIGHT + DELTA_X_COORDINATE; + SetUpButton(imgPosXBtn_, "图片X+", positionX_, positionY_); + positionX_ += BUTTON_WIDTH + DELTA_Y_COORDINATE; + SetUpButton(imgPosYBtn_, "图片Y+", positionX_, positionY_); +} + +void UITestCircleProgress::UIKit_CircleProgress_Test_SetLineColor_014() +{ + lineColorBtn_ = new UILabelButton(); + positionX_ = DELTA_X_COORDINATE_2; + positionY_ += BUTTON_HEIGHT + DELTA_Y_COORDINATE_2; + SetUpLabel("设置环形进度条前景线条颜色: ", positionX_, positionY_); + positionY_ += LABEL_HEIGHT + DELTA_X_COORDINATE; + SetUpButton(lineColorBtn_, "前景绿色", positionX_, positionY_); +} + +void UITestCircleProgress::UIKit_CircleProgress_Test_SetAngle_015() +{ + incStartAngleBtn_ = new UILabelButton(); + decStartAngleBtn_ = new UILabelButton(); + incEndAngleBtn_ = new UILabelButton(); + decEndAngleBtn_ = new UILabelButton(); + swapAngleBtn_ = new UILabelButton(); + positionX_ = DELTA_X_COORDINATE_2; + positionY_ += BUTTON_HEIGHT + DELTA_Y_COORDINATE_2; + SetUpLabel("设置环形进度条角度:", positionX_, positionY_); + positionY_ += LABEL_HEIGHT + DELTA_X_COORDINATE; + SetUpButton(incStartAngleBtn_, "起始角度+", positionX_, positionY_); + positionX_ += BUTTON_WIDTH + DELTA_Y_COORDINATE; + SetUpButton(decStartAngleBtn_, "起始角度-", positionX_, positionY_); + positionX_ = DELTA_X_COORDINATE_2; + positionY_ += BUTTON_HEIGHT + DELTA_Y_COORDINATE; + SetUpButton(incEndAngleBtn_, "结束角度+", positionX_, positionY_); + positionX_ += BUTTON_WIDTH + DELTA_Y_COORDINATE; + SetUpButton(decEndAngleBtn_, "结束角度-", positionX_, positionY_); + positionX_ = DELTA_X_COORDINATE_2; + positionY_ += BUTTON_HEIGHT + DELTA_Y_COORDINATE; + SetUpButton(swapAngleBtn_, "转换方向", positionX_, positionY_); +} + +bool UITestCircleProgress::OnClick(UIView& view, const ClickEvent& event) +{ + static uint16_t progress = 20; // 20: progress + static uint16_t step = 0; + static uint16_t width = 150; // 150: width + static uint16_t height = 150; // 150: height + static int16_t min = 0; + static int16_t max = 100; // 100: max value + static Point center = {75, 75}; // 75: position x 75: position y + static Point imgPos = {0, 0}; + static int16_t startAngle = 0; + static int16_t endAngle = 360; // 360: end angle + static int16_t radius = 50; // 50: radius + + if (&view == resetBtn_) { + circleProgress_->SetPosition(10, 10, 150, 150); // 10: x 10: y 150: width 150: height + progress = 100; // 100 progress + step = 0; + width = 150; // 150: width + height = 150; // 150: height + min = 0; + max = 100; // 100: max value + center = {75, 75}; // 75: position x 75: position y + startAngle = 0; + endAngle = 360; // 360: end angle + radius = 50; // 50: radius + imgPos = {0, 0}; + + circleProgress_->SetRange(max, min); + circleProgress_->SetValue(progress); + circleProgress_->SetCenterPosition(center.x, center.y); + circleProgress_->SetRadius(radius); + circleProgress_->SetStartAngle(startAngle); + circleProgress_->SetEndAngle(endAngle); + circleProgress_->SetStep(step); + circleProgress_->SetBackgroundStyle(StyleDefault::GetProgressBackgroundStyle()); + circleProgress_->SetForegroundStyle(StyleDefault::GetProgressForegroundStyle()); + circleProgress_->SetLineColor(Color::Red()); + circleProgress_->SetForegroundStyle(STYLE_LINE_WIDTH, 40); // 40: value + circleProgress_->SetForegroundStyle(STYLE_LINE_OPA, 127); // 127: value + circleProgress_->SetBackgroundImagePosition(imgPos.x, imgPos.y); + circleProgress_->SetProgressImagePosition(imgPos.x, imgPos.y); + circleProgress_->SetImage(static_cast(nullptr)); + circleProgress_->EnableBackground(false); + circleProgress_->LayoutCenterOfParent(); + } else if (&view == incProgressBtn_) { + progress++; + circleProgress_->SetValue(progress); + } else if (&view == decProgressBtn_) { + progress--; + circleProgress_->SetValue(progress); + } else if (&view == stepBtn_) { + step++; + circleProgress_->SetStep(step); + } else if (&view == incMinProgressBtn_) { + min++; + circleProgress_->SetRange(circleProgress_->GetRangeMax(), min); + } else if (&view == decMinProgressBtn_) { + min--; + circleProgress_->SetRange(circleProgress_->GetRangeMax(), min); + } else if (&view == incMaxProgressBtn_) { + max++; + circleProgress_->SetRange(max, circleProgress_->GetRangeMin()); + } else if (&view == decMaxProgressBtn_) { + max--; + circleProgress_->SetRange(max, circleProgress_->GetRangeMin()); + } else if (&view == imageBtn_) { + circleProgress_->SetImage(RED_IMAGE_PATH, BLUE_IMAGE_PATH); + } else if (&view == noImageBtn_) { + circleProgress_->SetImage(static_cast(nullptr)); + } else if (&view == setStyleBtn_) { + Style style = StyleDefault::GetDefaultStyle(); + style.lineColor_ = Color::White(); + circleProgress_->SetBackgroundStyle(style); + style.lineColor_ = Color::Blue(); + circleProgress_->SetForegroundStyle(style); + } else if (&view == getStyleBtn_) { + circleProgress_->SetBackgroundStyle(STYLE_LINE_COLOR, Color::Red().full); + circleProgress_->SetForegroundStyle(STYLE_LINE_COLOR, Color::Yellow().full); + } else if (&view == roundCapBtn_) { + circleProgress_->SetCapType(CapType::CAP_ROUND); + } else if (&view == noneCapBtn_) { + circleProgress_->SetCapType(CapType::CAP_NONE); + } else if (&view == enableBgBtn_) { + circleProgress_->EnableBackground(true); + } else if (&view == disableBgBtn_) { + circleProgress_->EnableBackground(false); + } else if (&view == incStartAngleBtn_) { + startAngle++; + circleProgress_->SetStartAngle(startAngle); + } else if (&view == decStartAngleBtn_) { + startAngle--; + circleProgress_->SetStartAngle(startAngle); + } else if (&view == incEndAngleBtn_) { + endAngle++; + circleProgress_->SetEndAngle(endAngle); + } else if (&view == decEndAngleBtn_) { + endAngle--; + circleProgress_->SetEndAngle(endAngle); + } else if (&view == swapAngleBtn_) { + int16_t angle = startAngle; + startAngle = endAngle; + endAngle = angle; + circleProgress_->SetStartAngle(startAngle); + circleProgress_->SetEndAngle(endAngle); + } else if (&view == centerXBtn_) { + center.x++; + circleProgress_->SetCenterPosition(center.x, circleProgress_->GetCenterPosition().y); + } else if (&view == centerYBtn_) { + center.y++; + circleProgress_->SetCenterPosition(circleProgress_->GetCenterPosition().x, center.y); + } else if (&view == incRadiusBtn_) { + radius++; + circleProgress_->SetRadius(radius); + } else if (&view == decRadiusBtn_) { + radius--; + circleProgress_->SetRadius(radius); + } else if (&view == incWidthBtn_) { + circleProgress_->SetBackgroundStyle(STYLE_LINE_WIDTH, + circleProgress_->GetBackgroundStyle(STYLE_LINE_WIDTH) + 1); + circleProgress_->SetForegroundStyle(STYLE_LINE_WIDTH, + circleProgress_->GetForegroundStyle(STYLE_LINE_WIDTH) + 1); + } else if (&view == decWidthBtn_) { + circleProgress_->SetBackgroundStyle(STYLE_LINE_WIDTH, + circleProgress_->GetBackgroundStyle(STYLE_LINE_WIDTH) - 1); + circleProgress_->SetForegroundStyle(STYLE_LINE_WIDTH, + circleProgress_->GetForegroundStyle(STYLE_LINE_WIDTH) - 1); + } else if (&view == imgPosXBtn_) { + imgPos.x++; + circleProgress_->SetBackgroundImagePosition(imgPos.x, imgPos.y); + circleProgress_->SetProgressImagePosition(imgPos.x, imgPos.y); + } else if (&view == imgPosXBtn_) { + imgPos.y++; + circleProgress_->SetBackgroundImagePosition(imgPos.x, imgPos.y); + circleProgress_->SetProgressImagePosition(imgPos.x, imgPos.y); + } else if (&view == lineColorBtn_) { + circleProgress_->SetLineColor(Color::Green()); + } + container_->Invalidate(); + return true; +} +} // namespace OHOS \ No newline at end of file diff --git a/test/uitest/test_progress_bar/ui_test_circle_progress.h b/test/uitest/test_progress_bar/ui_test_circle_progress.h new file mode 100755 index 0000000..0942881 --- /dev/null +++ b/test/uitest/test_progress_bar/ui_test_circle_progress.h @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef UI_TEST_CIRCLE_PROGRESS_H +#define UI_TEST_CIRCLE_PROGRESS_H + +#include "components/ui_circle_progress.h" +#include "components/ui_label_button.h" +#include "components/ui_scroll_view.h" +#include "ui_test.h" + +namespace OHOS { +class UITestCircleProgress : public UITest, public UIView::OnClickListener { +public: + UITestCircleProgress() {} + ~UITestCircleProgress() {} + void SetUp() override; + void TearDown() override; + UIView* GetTestView() override; + + void SetUpButton(UILabelButton* btn, const char* title, int16_t x, int16_t y); + void SetUpLabel(const char* title, int16_t x, int16_t y) const; + + bool OnClick(UIView& view, const ClickEvent& event) override; + + void UIKit_CircleProgress_Test_UICircleProgress_001(); + void UIKit_CircleProgress_Test_SetValue_002(); + void UIKit_CircleProgress_Test_SetImage_003(); + void UIKit_CircleProgress_Test_SetStyle_004(); + void UIKit_CircleProgress_Test_GetStyle_005(); + void UIKit_CircleProgress_Test_SetCapType_006(); + void UIKit_CircleProgress_Test_SetStep_007(); + void UIKit_CircleProgress_Test_SetRange_008(); + void UIKit_CircleProgress_Test_EnableBackground_009(); + void UIKit_CircleProgress_Test_SetCenter_010(); + void UIKit_CircleProgress_Test_SetRadius_011(); + void UIKit_CircleProgress_Test_SetLineWidth_012(); + void UIKit_CircleProgress_Test_SetImagePosition_013(); + void UIKit_CircleProgress_Test_SetLineColor_014(); + void UIKit_CircleProgress_Test_SetAngle_015(); + +private: + UIScrollView* container_ = nullptr; + UIScrollView* scroll_ = nullptr; + UICircleProgress* circleProgress_ = nullptr; + UIViewGroup* uiViewGroupFrame_ = nullptr; + + UILabelButton* resetBtn_ = nullptr; + UILabelButton* incProgressBtn_ = nullptr; + UILabelButton* decProgressBtn_ = nullptr; + UILabelButton* incMinProgressBtn_ = nullptr; + UILabelButton* decMinProgressBtn_ = nullptr; + UILabelButton* incMaxProgressBtn_ = nullptr; + UILabelButton* decMaxProgressBtn_ = nullptr; + UILabelButton* centerXBtn_ = nullptr; + UILabelButton* centerYBtn_ = nullptr; + UILabelButton* incRadiusBtn_ = nullptr; + UILabelButton* decRadiusBtn_ = nullptr; + UILabelButton* incWidthBtn_ = nullptr; + UILabelButton* decWidthBtn_ = nullptr; + UILabelButton* incStartAngleBtn_ = nullptr; + UILabelButton* decStartAngleBtn_ = nullptr; + UILabelButton* incEndAngleBtn_ = nullptr; + UILabelButton* decEndAngleBtn_ = nullptr; + UILabelButton* swapAngleBtn_ = nullptr; + UILabelButton* stepBtn_ = nullptr; + UILabelButton* imageBtn_ = nullptr; + UILabelButton* noImageBtn_ = nullptr; + UILabelButton* setStyleBtn_ = nullptr; + UILabelButton* getStyleBtn_ = nullptr; + UILabelButton* roundCapBtn_ = nullptr; + UILabelButton* noneCapBtn_ = nullptr; + UILabelButton* enableBgBtn_ = nullptr; + UILabelButton* disableBgBtn_ = nullptr; + UILabelButton* imgPosXBtn_ = nullptr; + UILabelButton* imgPosYBtn_ = nullptr; + UILabelButton* lineColorBtn_ = nullptr; +}; +} // namespace OHOS +#endif // UI_TEST_CIRCLE_PROGRESS_H diff --git a/test/uitest/test_qrcode/ui_test_qrcode.cpp b/test/uitest/test_qrcode/ui_test_qrcode.cpp new file mode 100755 index 0000000..6361cdf --- /dev/null +++ b/test/uitest/test_qrcode/ui_test_qrcode.cpp @@ -0,0 +1,234 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "ui_test_qrcode.h" +#include "common/screen.h" +#include "font/ui_font.h" + +namespace OHOS { +namespace { +const int16_t TITLE_HEIGHT = 29; +} // namespace + +void UITestQrcode::SetUp() +{ + if (container_ == nullptr) { + container_ = new UIScrollView(); + container_->SetThrowDrag(true); + container_->SetHorizontalScrollState(false); + container_->Resize(Screen::GetInstance().GetWidth(), Screen::GetInstance().GetHeight() - BACK_BUTTON_HEIGHT); + } +} + +void UITestQrcode::TearDown() +{ + DeleteChildren(container_); + container_ = nullptr; +} + +const UIView* UITestQrcode::GetTestView() +{ + UIKitUIQrcodeTestDisplay001(); + UIKitUIQrcodeTestDisplay002(); + UIKitUIQrcodeTestDisplay003(); + UIKitUIQrcodeTestDisplay004(); + UIKitUIQrcodeTestDisplay005(); + UIKitUIQrcodeTestDisplay006(); + UIKitUIQrcodeTestDisplay007(); + UIKitUIQrcodeTestDisplay008(); + UIKitUIQrcodeTestDisplay009(); + return container_; +} + +UIViewGroup* UITestQrcode::CreateTestCaseGroup(const char* title) const +{ + UIViewGroup* group = new UIViewGroup(); + group->SetStyle(STYLE_BACKGROUND_COLOR, Color::Black().full); + group->SetStyle(STYLE_BACKGROUND_OPA, OPA_OPAQUE); + group->SetPosition(0, 0); + UILabel* titleLabel = new UILabel(); + titleLabel->SetPosition(0, 0, Screen::GetInstance().GetWidth(), TITLE_HEIGHT); + titleLabel->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); + titleLabel->SetText(title); + group->Add(titleLabel); + return group; +} + +void UITestQrcode::UIKitUIQrcodeTestDisplay001() +{ + if (container_ != nullptr) { + UIViewGroup* group = CreateTestCaseGroup(" display qrcode 60 * 60"); + group->Resize(Screen::GetInstance().GetWidth(), 100); // 100 : height + group->SetViewId("UIKitUIQrcodeTestDisplay001"); + + UIQrcode* qrcode = new UIQrcode(); + qrcode->SetPosition(20, 30, 60, 60); // 20 x 30 y 150 width 60 height + const char* str = "Hello\n 鸿蒙轻量级GUI"; + qrcode->SetQrcodeInfo(str); + group->Add(qrcode); + container_->Add(group); + } +} +void UITestQrcode::UIKitUIQrcodeTestDisplay002() +{ + if (container_ != nullptr) { + UIViewGroup* group = CreateTestCaseGroup(" display qrcode 120 * 250"); + group->Resize(Screen::GetInstance().GetWidth(), 300); // 300 : height + group->SetViewId("UIKitUIQrcodeTestDisplay002"); + + UIQrcode* qrcode = new UIQrcode(); + qrcode->SetPosition(20, 30); // 20 x 30 y + const char* str = "Hello\n 鸿蒙轻量级GUI"; + qrcode->SetQrcodeInfo(str); + qrcode->SetWidth(120); // 120 width + qrcode->SetHeight(250); // 250 height + group->Add(qrcode); + container_->Add(group); + group->LayoutBottomToSibling("UIKitUIQrcodeTestDisplay001", 10); // 10: height + } +} + +void UITestQrcode::UIKitUIQrcodeTestDisplay003() +{ + if (container_ != nullptr) { + UIViewGroup* group = CreateTestCaseGroup(" display qrcode 400 * 200, MAX_LENGTH"); + group->Resize(Screen::GetInstance().GetWidth(), 450); // 450 : height + group->SetViewId("UIKitUIQrcodeTestDisplay003"); + + UIQrcode* qrcode = new UIQrcode(); + qrcode->SetPosition(20, 30); // 20 x 30 y + const char* str = + "Hello\n GUIddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd \ + ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd \ + ddddddddddddddddddddddddddddddddddddddddddddddddddddddd"; + ColorType backgroundColor = Color::Green(); + ColorType qrColor = Color::Blue(); + qrcode->SetQrcodeInfo(str, backgroundColor, qrColor); + qrcode->SetWidth(400); // 400 width + qrcode->SetHeight(200); // 200 height + group->Add(qrcode); + container_->Add(group); + group->LayoutBottomToSibling("UIKitUIQrcodeTestDisplay002", 10); // 10: height + } +} + +void UITestQrcode::UIKitUIQrcodeTestDisplay004() +{ + if (container_ != nullptr) { + UIViewGroup* group = CreateTestCaseGroup("qrcode 50 * 50, width is less than minimum qrcode size, error!"); + group->Resize(Screen::GetInstance().GetWidth(), 100); // 100 : height + group->SetViewId("UIKitUIQrcodeTestDisplay004"); + + UIQrcode* qrcode = new UIQrcode(); + qrcode->SetPosition(20, 30, 50, 50); // 20 x 30 y 50 width 50 height + const char* str = + "Hello\n GUIddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd \ + ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd \ + dddddddddddddddddddddddddddddddddddddddddddddddddddddd"; + qrcode->SetQrcodeInfo(str); + group->Add(qrcode); + container_->Add(group); + group->LayoutBottomToSibling("UIKitUIQrcodeTestDisplay003", 10); // 10: height + } +} + +void UITestQrcode::UIKitUIQrcodeTestDisplay005() +{ + if (container_ != nullptr) { + UIViewGroup* group = CreateTestCaseGroup("qrcode 250 * 250, val length is greater than MAX_LENGTH, error!"); + group->Resize(Screen::GetInstance().GetWidth(), 300); // 300 : height + group->SetViewId("UIKitUIQrcodeTestDisplay005"); + + UIQrcode* qrcode = new UIQrcode(); + qrcode->SetPosition(20, 30, 250, 250); // 20 x 30 y 250 width 250 height + const char* str = + "Hello\n GUIddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd \ + ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd \ + ddddddddddddddddddddddddddddddddddddddddddddddddddddddddd"; + qrcode->SetQrcodeInfo(str); + group->Add(qrcode); + container_->Add(group); + group->LayoutBottomToSibling("UIKitUIQrcodeTestDisplay004", 10); // 10: height + } +} + +void UITestQrcode::UIKitUIQrcodeTestDisplay006() +{ + if (container_ != nullptr) { + UIViewGroup* group = CreateTestCaseGroup("qrcode 250 * 250, str = \"\" "); + group->Resize(Screen::GetInstance().GetWidth(), 300); // 300 : height + group->SetViewId("UIKitUIQrcodeTestDisplay006"); + + UIQrcode* qrcode = new UIQrcode(); + qrcode->SetPosition(20, 30, 250, 250); // 20 x 30 y 250 width 250 height + const char* str = ""; + qrcode->SetQrcodeInfo(str); + group->Add(qrcode); + container_->Add(group); + group->LayoutBottomToSibling("UIKitUIQrcodeTestDisplay005", 10); // 10: height + } +} + +void UITestQrcode::UIKitUIQrcodeTestDisplay007() +{ + if (container_ != nullptr) { + UIViewGroup* group = CreateTestCaseGroup("qrcode 250 * 250, str = \" \""); + group->Resize(Screen::GetInstance().GetWidth(), 300); // 300 : height + group->SetViewId("UIKitUIQrcodeTestDisplay007"); + + UIQrcode* qrcode = new UIQrcode(); + qrcode->SetPosition(20, 30, 250, 250); // 20 x 30 y 250 width 250 height + const char* str = " "; + qrcode->SetQrcodeInfo(str); + group->Add(qrcode); + container_->Add(group); + group->LayoutBottomToSibling("UIKitUIQrcodeTestDisplay006", 10); // 10: height + } +} + +void UITestQrcode::UIKitUIQrcodeTestDisplay008() +{ + if (container_ != nullptr) { + UIViewGroup* group = CreateTestCaseGroup("qrcode 250 * 250, str = nullptr"); + group->Resize(Screen::GetInstance().GetWidth(), 300); // 300 : height + group->SetViewId("UIKitUIQrcodeTestDisplay008"); + + UIQrcode* qrcode = new UIQrcode(); + qrcode->SetPosition(20, 30, 250, 250); // 20 x 30 y 250 width 250 height + const char* str = nullptr; + qrcode->SetQrcodeInfo(str); + group->Add(qrcode); + container_->Add(group); + group->LayoutBottomToSibling("UIKitUIQrcodeTestDisplay007", 10); // 10: height + } +} + +void UITestQrcode::UIKitUIQrcodeTestDisplay009() +{ + if (container_ != nullptr) { + UIViewGroup* group = CreateTestCaseGroup("qrcode 250 * 250, position x = -50"); + group->Resize(Screen::GetInstance().GetWidth(), 300); // 300 : height + group->SetViewId("UIKitUIQrcodeTestDisplay009"); + + UIQrcode* qrcode = new UIQrcode(); + qrcode->SetPosition(-50, 30, 250, 250); // -50 x 30 y 250 width 250 height + const char* str = "Hello GUI"; + qrcode->SetQrcodeInfo(str); + group->Add(qrcode); + container_->Add(group); + group->LayoutBottomToSibling("UIKitUIQrcodeTestDisplay008", 10); // 10: height + } +} +} // namespace OHOS \ No newline at end of file diff --git a/test/uitest/test_qrcode/ui_test_qrcode.h b/test/uitest/test_qrcode/ui_test_qrcode.h new file mode 100755 index 0000000..d9d89b9 --- /dev/null +++ b/test/uitest/test_qrcode/ui_test_qrcode.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef UI_TEST_QRCODE_H +#define UI_TEST_QRCODE_H + +#include "components/ui_qrcode.h" +#include "components/ui_scroll_view.h" +#include "ui_test.h" + +namespace OHOS { +class UITestQrcode : public UITest { +public: + UITestQrcode() {} + ~UITestQrcode() {} + void SetUp() override; + void TearDown() override; + const UIView* GetTestView() override; + /** + * @brief Test display UIQrcode + */ + void UIKitUIQrcodeTestDisplay001(); + void UIKitUIQrcodeTestDisplay002(); + void UIKitUIQrcodeTestDisplay003(); + void UIKitUIQrcodeTestDisplay004(); + void UIKitUIQrcodeTestDisplay005(); + void UIKitUIQrcodeTestDisplay006(); + void UIKitUIQrcodeTestDisplay007(); + void UIKitUIQrcodeTestDisplay008(); + void UIKitUIQrcodeTestDisplay009(); +private: + UIScrollView* container_ = nullptr; + UIViewGroup* CreateTestCaseGroup(const char* title) const; +}; +} // namespace OHOS +#endif // UI_TEST_QRCODE_H \ No newline at end of file diff --git a/test/uitest/test_render/ui_test_render.cpp b/test/uitest/test_render/ui_test_render.cpp new file mode 100755 index 0000000..ac145ad --- /dev/null +++ b/test/uitest/test_render/ui_test_render.cpp @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "ui_test_render.h" +#include "common/screen.h" + +namespace OHOS { +void UITestRender::SetUp() +{ + if (container_ == nullptr) { + container_ = new UIScrollView(); + container_->Resize(Screen::GetInstance().GetWidth(), Screen::GetInstance().GetHeight() - BACK_BUTTON_HEIGHT); + } +} + +void UITestRender::TearDown() +{ + DeleteChildren(container_); + container_ = nullptr; +} + +UIView* UITestRender::GetTestView() +{ + UIKit_Render_Test_Render_001(); + UIKit_Render_Test_RenderMeasure_001(); + return container_; +} + +class TestRenderClickListener : public UIView::OnClickListener { +public: + bool OnClick(UIView& view, const ClickEvent& event) override + { + static uint8_t r = 20; + static uint8_t g = 120; + static uint8_t b = 50; + view.SetStyle(STYLE_BACKGROUND_COLOR, Color::GetColorFromRGB(r, g, b).full); + view.Invalidate(); + + r = r + 30; // 30: red add + g = g + 30; // 30: green add + b = b + 30; // 30: blue add + return true; + } +}; + +UIViewGroup* UITestRender::CreateTestCaseGroup() const +{ + UIViewGroup* group = new UIViewGroup(); + group->Resize(Screen::GetInstance().GetWidth(), 200); // 200: height + return group; +} + +UILabel* UITestRender::CreateTitleLabel() const +{ + UILabel* label = new UILabel(); + // 216: label width + label->SetPosition(TEXT_DISTANCE_TO_LEFT_SIDE, TEXT_DISTANCE_TO_TOP_SIDE, 216, TITLE_LABEL_DEFAULT_HEIGHT); + label->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); + return label; +} + +void UITestRender::UIKit_Render_Test_Render_001() +{ + if (container_ == nullptr) { + return; + } + + UIViewGroup* group = CreateTestCaseGroup(); + group->SetViewId("UIKit_Render_Test_Render_001"); + group->SetPosition(0, 0); + + UILabel* label = CreateTitleLabel(); + group->Add(label); + label->SetText("UIKit绘制效果:"); + + UIView* view = new UIView(); + view->Resize(200, 50); // 200: width 50: height + view->SetPosition(50, 50); // 50: position x 50: position y + view->SetStyle(STYLE_BACKGROUND_COLOR, Color::Yellow().full); + group->Add(view); + view->SetTouchable(true); + view->SetOnClickListener(new TestRenderClickListener()); + + UIView* view1 = new UIView(); + view1->Resize(100, 50); // 100: width 50: height + view1->SetPosition(50, 120); // 50: position x 120: position y + view1->SetStyle(STYLE_BACKGROUND_COLOR, Color::Green().full); + view1->SetTouchable(true); + view1->SetOnClickListener(new TestRenderClickListener()); + group->Add(view1); + container_->Add(group); +} + +void UITestRender::UIKit_Render_Test_RenderMeasure_001() +{ + if (container_ == nullptr) { + return; + } + + UIViewGroup* group = CreateTestCaseGroup(); + group->SetViewId("UIKit_Render_Test_RenderMeasure_001"); + container_->Add(group); + + UILabel* label = CreateTitleLabel(); + group->Add(label); + // 2: half of screen width + label->Resize(Screen::GetInstance().GetWidth() / 2, TITLE_LABEL_DEFAULT_HEIGHT); + label->SetText("UIKit绘制Measure效果:"); + group->Add(label); + + testLabel_ = new UILabel(); + group->Add(testLabel_); + testLabel_->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE, VIEW_DISTANCE_TO_TOP_SIDE); + testLabel_->Resize(150, 80); // 150: width 80: height + testLabel_->SetViewId("label_text"); + testLabel_->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); + testLabel_->SetLineBreakMode(UILabel::LINE_BREAK_WRAP); + testLabel_->SetText("示例文字,示例文字"); + + labelButton_ = new UILabelButton(); + group->Add(labelButton_); + labelButton_->Resize(BUTTON_WIDHT3, BUTTON_HEIGHT3); + labelButton_->SetText("更新label"); + labelButton_->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); + labelButton_->SetStyleForState(STYLE_BORDER_RADIUS, BUTTON_STYLE_BORDER_RADIUS_VALUE, UIButton::RELEASED); + labelButton_->SetStyleForState(STYLE_BORDER_RADIUS, BUTTON_STYLE_BORDER_RADIUS_VALUE, UIButton::PRESSED); + labelButton_->SetStyleForState(STYLE_BACKGROUND_COLOR, BUTTON_STYLE_BACKGROUND_COLOR_VALUE, UIButton::RELEASED); + labelButton_->SetStyleForState(STYLE_BACKGROUND_COLOR, BUTTON_STYLE_BACKGROUND_COLOR_PRESS, UIButton::PRESSED); + labelButton_->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE, VIEW_DISTANCE_TO_TOP_SIDE); + labelButton_->SetOnClickListener(this); + labelButton_->LayoutBottomToSibling("label_text"); // 10: offset + + group->LayoutBottomToSibling("UIKit_Render_Test_Render_001", 10); // 10: offset +} + +bool UITestRender::OnClick(UIView& view, const ClickEvent& event) +{ + if (&view == labelButton_) { + testLabel_->SetFont(DEFAULT_VECTOR_FONT_FILENAME, 15); // 18: font size + } + return true; +} +} // namespace OHOS \ No newline at end of file diff --git a/test/uitest/test_render/ui_test_render.h b/test/uitest/test_render/ui_test_render.h new file mode 100755 index 0000000..94a2e8d --- /dev/null +++ b/test/uitest/test_render/ui_test_render.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef UI_TEST_RENDER_H +#define UI_TEST_RENDER_H + +#include "components/ui_label.h" +#include "components/ui_label_button.h" +#include "components/ui_scroll_view.h" +#include "ui_test.h" + +namespace OHOS { +class UITestRender : public UITest, public UIView::OnClickListener { +public: + UITestRender() : container_(nullptr) {} + ~UITestRender() {} + void SetUp() override; + void TearDown() override; + UIView* GetTestView() override; + bool OnClick(UIView& view, const ClickEvent& event) override; + + /** + * @brief Test render Function + */ + void UIKit_Render_Test_Render_001(); + + /** + * @brief Test render measure Function + */ + void UIKit_Render_Test_RenderMeasure_001(); + +private: + UIViewGroup* CreateTestCaseGroup() const; + UILabel* CreateTitleLabel() const; + UIScrollView* container_ = nullptr; + UILabel* testLabel_ = nullptr; + UILabelButton* labelButton_ = nullptr; +}; +} // namespace OHOS +#endif // UI_TEST_RENDER_H diff --git a/test/uitest/test_rotate_input/ui_test_rotate_input.cpp b/test/uitest/test_rotate_input/ui_test_rotate_input.cpp new file mode 100644 index 0000000..61c8134 --- /dev/null +++ b/test/uitest/test_rotate_input/ui_test_rotate_input.cpp @@ -0,0 +1,361 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "ui_test_rotate_input.h" +#include "common/screen.h" +#include "components/ui_label.h" +#include "components/ui_label_button.h" +#include "cstdio" +#include "dock/focus_manager.h" + +#if ENABLE_ROTATE_INPUT +namespace OHOS { +static int16_t g_blank = 20; +static int16_t g_listW = 200; +static int16_t g_listH = 400; +static int16_t g_scrollH = 200; +static int16_t g_scrollW = 400; +static int16_t g_buttonH = 500; +static int16_t g_buttonW = 500; +static int16_t g_smallButtonH = 80; +static int16_t g_smallButtonW = 200; +static int16_t g_swipeH = 200; +static int16_t g_swipeW = 400; +static int16_t g_sliderW = 40; +static int16_t g_sliderH = 300; +static const char* g_pickerRange[] = { "A0", "B1", "C2", "D3", "E4", "F5", "G6", "H7", "I8", "J9", "K10", "L11" }; + +#if ENABLE_MOTOR +void Print(MotorType motorType) +{ + switch (motorType) { + case MotorType::MOTOR_TYPE_ONE: + printf("MOTOR_TYPE_ONE\n"); + break; + case MotorType::MOTOR_TYPE_TWO: + printf("MOTOR_TYPE_TWO\n"); + break; + default: + break; + } +} +#endif + +void UITestRotateInput::SetUp() +{ + if (container_ == nullptr) { + container_ = new UIScrollView(); + container_->SetOnTouchListener(this); + container_->Resize(Screen::GetInstance().GetWidth(), Screen::GetInstance().GetHeight()); + container_->SetThrowDrag(true); + container_->SetRotateFactor(20); // 20 : rotate factor for container + container_->RequestFocus(); + container_->SetReboundSize(50); // 50 : rebound size + } + if (adapterData_ == nullptr) { + adapterData_ = new List(); + adapterData_->PushBack("000"); + adapterData_->PushBack("111"); + adapterData_->PushBack("222"); + adapterData_->PushBack("333"); + adapterData_->PushBack("444"); + adapterData_->PushBack("555"); + adapterData_->PushBack("666"); + adapterData_->PushBack("777"); + adapterData_->PushBack("888"); + adapterData_->PushBack("999"); + adapterData_->PushBack("///"); + adapterData_->PushBack("***"); + adapterData_->PushBack("+++"); + adapterData_->PushBack("---"); + adapterData_->PushBack("..."); + adapterData_->PushBack("@@@"); + adapterData_->PushBack("000"); + adapterData_->PushBack("111"); + adapterData_->PushBack("222"); + adapterData_->PushBack("333"); + adapterData_->PushBack("444"); + adapterData_->PushBack("555"); + adapterData_->PushBack("666"); + adapterData_->PushBack("777"); + adapterData_->PushBack("888"); + adapterData_->PushBack("999"); + adapterData_->PushBack("///"); + adapterData_->PushBack("***"); + adapterData_->PushBack("+++"); + adapterData_->PushBack("---"); + adapterData_->PushBack("..."); + adapterData_->PushBack("@@@"); + } +#if ENABLE_MOTOR + FocusManager::GetInstance()->RegisterMotorFunc(Print); +#endif +} + +void UITestRotateInput::TearDown() +{ + container_->ClearFocus(); + container_->Remove(timePicker_); + container_->Remove(picker_); + DeleteChildren(container_); + container_ = nullptr; + if (adapterData_ != nullptr) { + adapterData_->Clear(); + delete adapterData_; + adapterData_ = nullptr; + } + if (adapter_ != nullptr) { + delete adapter_; + adapter_ = nullptr; + } + lastX_ = 0; + lastY_ = 0; + list_ = nullptr; + scroll_ = nullptr; + swipe_ = nullptr; + timePicker_ = nullptr; + slider_ = nullptr; + picker_ = nullptr; +} + +const UIView* UITestRotateInput::GetTestView() +{ + UIKit_Rotate_Event_List_001(); + UIKit_Rotate_Event_Scroll_View_002(); + UIKit_Rotate_Event_Swipe_View_003(); + UIKit_Rotate_Event_Slider_004(); + UIKit_Rotate_Event_Time_Picker_005(); + UIKit_Rotate_Event_Picker_006(); + return container_; +} + +void UITestRotateInput::UIKit_Rotate_Event_List_001() +{ + if (container_ == nullptr) { + return; + } + UILabel* label = GetTitleLabel("UIList Test"); + container_->Add(label); + label->SetPosition(0, lastY_ + g_blank); + if (adapter_ == nullptr) { + adapter_ = new TextAdapter(); + } + adapter_->SetData(adapterData_); + if (list_ == nullptr) { + list_ = new UIList(UIList::VERTICAL); + } + list_->SetStyle(STYLE_BACKGROUND_COLOR, Color::Black().full); + list_->SetPosition(0, label->GetY() + g_blank, g_listW, g_listH - 200); // 200: mean list reduce height + list_->SetStartIndex(6); // 6 : list start index + list_->SetAdapter(adapter_); + list_->SetOnTouchListener(this); + list_->SetThrowDrag(true); + list_->SetRotateFactor(10); // 10 : rotate factor + list_->SetReboundSize(50); // 50 : rebound size + container_->Add(list_); + SetLastPos(list_); +} + +void UITestRotateInput::UIKit_Rotate_Event_Scroll_View_002() +{ + if (container_ == nullptr) { + return; + } + UILabel* label = GetTitleLabel("UIScrollView Test"); + container_->Add(label); + label->SetPosition(0, lastY_ + g_blank); + if (scroll_ == nullptr) { + scroll_ = new UIScrollView(); + } + scroll_->SetStyle(STYLE_BACKGROUND_COLOR, Color::Black().full); + scroll_->SetPosition(0, label->GetY() + g_blank, g_scrollW, g_scrollH); + scroll_->SetXScrollBarVisible(true); + scroll_->SetYScrollBarVisible(true); + scroll_->SetRotateFactor(10); // 10 : rotateFactor + UIButton* btn = new UIButton(); + btn->SetPosition(0, 0, g_buttonW, g_buttonH); + scroll_->Add(btn); + scroll_->SetThrowDrag(true); + scroll_->SetOnTouchListener(this); + scroll_->SetReboundSize(50); // 50 : rebound size + SetLastPos(scroll_); + container_->Add(scroll_); +} + +void UITestRotateInput::UIKit_Rotate_Event_Swipe_View_003() +{ + if (container_ == nullptr) { + return; + } + UILabel* label = GetTitleLabel("UISwipeView Test"); + container_->Add(label); + label->SetPosition(0, lastY_ + g_blank); + if (swipe_ == nullptr) { + swipe_ = new UISwipeView(UISwipeView::HORIZONTAL); + } + swipe_->SetStyle(STYLE_BACKGROUND_COLOR, Color::Black().full); + swipe_->SetPosition(0, label->GetY() + g_blank, g_swipeW, g_swipeH); + swipe_->SetBlankSize(100); // 100 is blank size + UILabelButton* btn1 = new UILabelButton(); + UILabelButton* btn2 = new UILabelButton(); + UILabelButton* btn3 = new UILabelButton(); + UILabelButton* btn4 = new UILabelButton(); + UILabelButton* btn5 = new UILabelButton(); + UILabelButton* btn6 = new UILabelButton(); + UILabelButton* btn7 = new UILabelButton(); + btn1->SetPosition(0, 0, g_smallButtonW, g_smallButtonH); + btn2->SetPosition(0, 0, g_smallButtonW, g_smallButtonH); + btn3->SetPosition(0, 0, g_smallButtonW, g_smallButtonH); + btn4->SetPosition(0, 0, g_smallButtonW, g_smallButtonH); + btn5->SetPosition(0, 0, g_smallButtonW, g_smallButtonH); + btn6->SetPosition(0, 0, g_smallButtonW, g_smallButtonH); + btn7->SetPosition(0, 0, g_smallButtonW, g_smallButtonH); + btn1->SetText("Button 1"); + btn2->SetText("Button 2"); + btn3->SetText("Button 3"); + btn4->SetText("Button 4"); + btn5->SetText("Button 5"); + btn6->SetText("Button 6"); + btn7->SetText("Button 7"); + swipe_->Add(btn1); + swipe_->Add(btn2); + swipe_->Add(btn3); + swipe_->Add(btn4); + swipe_->Add(btn5); + swipe_->Add(btn6); + swipe_->Add(btn7); + swipe_->SetOnTouchListener(this); + swipe_->SetRotateFactor(30); // 30 : rotate factor + container_->Add(swipe_); + SetLastPos(swipe_); +} + +void UITestRotateInput::UIKit_Rotate_Event_Slider_004() +{ + if (container_ == nullptr) { + return; + } + UILabel* label = GetTitleLabel("UISlider Test"); + container_->Add(label); + label->SetPosition(0, lastY_ + g_blank); + if (slider_ == nullptr) { + slider_ = new UISlider(); + } + slider_->SetPosition(50, label->GetY() + g_blank, g_sliderW, g_sliderH); // 50: position x + slider_->SetValidHeight(200); // 200: valid height + slider_->SetValue(0); // 0: progress bar current value + slider_->SetDirection(UISlider::Direction::DIR_BOTTOM_TO_TOP); + slider_->SetStyle(STYLE_BACKGROUND_COLOR, Color::Gray().full); + slider_->SetOnTouchListener(this); + container_->Add(slider_); + SetLastPos(slider_); +} +void UITestRotateInput::UIKit_Rotate_Event_Time_Picker_005() +{ + if (container_ == nullptr) { + return; + } + UILabel* label = GetTitleLabel("UITimePicker Test"); + container_->Add(label); + label->SetPosition(0, lastY_ + g_blank); + if (timePicker_ == nullptr) { + timePicker_ = new UITimePicker(); + } + timePicker_->EnableSecond(true); + timePicker_->SetPosition(0, label->GetY() + g_blank, g_listW, g_listH); + timePicker_->SetItemHeight(50); // 50 height + + UIView* hour = timePicker_->GetChildById("hour"); + if (hour == nullptr) { + return; + } + hour->SetOnTouchListener(this); + + UIView* minute = timePicker_->GetChildById("minute"); + if (minute == nullptr) { + return; + } + minute->SetOnTouchListener(this); + + UIView* second = timePicker_->GetChildById("second"); + if (second == nullptr) { + return; + } + second->SetOnTouchListener(this); + + container_->Add(timePicker_); + SetLastPos(timePicker_); +} + +void UITestRotateInput::UIKit_Rotate_Event_Picker_006() +{ + if (container_ == nullptr) { + return; + } + UILabel* label = GetTitleLabel("UIPicker Test"); + container_->Add(label); + label->SetPosition(0, lastY_ + g_blank); + if (picker_ == nullptr) { + picker_ = new UIPicker(); + } + picker_->SetPosition(0, label->GetY() + g_blank, g_listW, g_listH); + picker_->SetItemHeight(50); // 50: height + picker_->SetValues(g_pickerRange, sizeof(g_pickerRange) / sizeof(g_pickerRange[0])); + picker_->SetOnTouchListener(this); + container_->Add(picker_); + SetLastPos(picker_); +} +bool UITestRotateInput::OnPress(UIView& view, const PressEvent& event) +{ + if (&view == container_) { + container_->RequestFocus(); + return true; + } else if (&view == list_) { + list_->RequestFocus(); + return true; + } else if (&view == scroll_) { + scroll_->RequestFocus(); + return true; + } else if (&view == swipe_) { + swipe_->RequestFocus(); + return true; + } else if (&view == slider_) { + slider_->RequestFocus(); + return true; + } else if (&view == timePicker_->GetChildById(UITimePicker::HOUR_LIST_NAME)) { + view.RequestFocus(); + return true; + } else if (&view == timePicker_->GetChildById(UITimePicker::MIN_LIST_NAME)) { + view.RequestFocus(); + return true; + } else if (&view == timePicker_->GetChildById(UITimePicker::SEC_LIST_NAME)) { + view.RequestFocus(); + return true; + } else if (&view == picker_) { + picker_->RequestFocus(); + return true; + } + return false; +} +void UITestRotateInput::SetLastPos(UIView* view) +{ + if (view == nullptr) { + return; + } + lastX_ = view->GetX(); + lastY_ = view->GetY() + view->GetHeight(); +} +} // namespace OHOS +#endif diff --git a/test/uitest/test_rotate_input/ui_test_rotate_input.h b/test/uitest/test_rotate_input/ui_test_rotate_input.h new file mode 100644 index 0000000..38e348a --- /dev/null +++ b/test/uitest/test_rotate_input/ui_test_rotate_input.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef UI_TEST_ROTATE_INPUT_H +#define UI_TEST_ROTATE_INPUT_H + +#include "components/ui_list.h" +#include "components/ui_scroll_view.h" +#include "components/ui_slider.h" +#include "components/ui_swipe_view.h" +#include "components/ui_time_picker.h" +#include "ui_test.h" + +#if ENABLE_ROTATE_INPUT +namespace OHOS { +class UITestRotateInput : public UITest, UIView::OnTouchListener { +public: + UITestRotateInput() {} + ~UITestRotateInput() {} + void SetUp() override; + void TearDown() override; + const UIView* GetTestView() override; + void UIKit_Rotate_Event_List_001(); + void UIKit_Rotate_Event_Scroll_View_002(); + void UIKit_Rotate_Event_Swipe_View_003(); + void UIKit_Rotate_Event_Slider_004(); + void UIKit_Rotate_Event_Time_Picker_005(); + void UIKit_Rotate_Event_Picker_006(); + bool OnPress(UIView& view, const PressEvent& event) override; + +private: + void SetLastPos(UIView* view); + UIScrollView* container_ = nullptr; + UIList* list_ = nullptr; + UIScrollView* scroll_ = nullptr; + UISwipeView* swipe_ = nullptr; + UITimePicker* timePicker_ = nullptr; + UISlider* slider_ = nullptr; + List* adapterData_ = nullptr; + TextAdapter* adapter_ = nullptr; + int16_t lastX_ = 0; + int16_t lastY_ = 0; + UIPicker* picker_ = nullptr; +}; +} // namespace OHOS +#endif // UI_TEST_ROTATE_INPUT_H +#endif diff --git a/test/uitest/test_screenshot/ui_test_screenshot.cpp b/test/uitest/test_screenshot/ui_test_screenshot.cpp new file mode 100755 index 0000000..a2d87dd --- /dev/null +++ b/test/uitest/test_screenshot/ui_test_screenshot.cpp @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "ui_test_screenshot.h" +#if ENABLE_DEBUG +#include "common/screen.h" +#include "components/ui_image_view.h" +#include "imgdecode/cache_manager.h" +#include "test_resource_config.h" + +namespace OHOS { +void UITestScreenshot::SetUp() +{ + if (container_ == nullptr) { + container_ = new UIScrollView(); + container_->Resize(Screen::GetInstance().GetWidth(), Screen::GetInstance().GetHeight() - BACK_BUTTON_HEIGHT); + container_->SetStyle(STYLE_BACKGROUND_COLOR, Color::Gray().full); + } +} + +void UITestScreenshot::TearDown() +{ + DeleteChildren(container_); + container_ = nullptr; +} + +UIView* UITestScreenshot::GetTestView() +{ + UIKit_SCREENSHOT_TEST_001(); + return container_; +} + +class TestScreenshotOnClickListener : public UIView::OnClickListener { +public: + TestScreenshotOnClickListener(UIView* uiView) : uiView_(uiView) {} + ~TestScreenshotOnClickListener() {} + bool OnClick(UIView& view, const ClickEvent& event) override + { + UIScreenshot::GetInstance()->ScreenshotToFile("/storage/data/screenshot.bin"); + uiView_->Invalidate(); + return true; + } + +private: + UIView* uiView_; +}; + +class TestSetScreenshotOnClickListener : public UIView::OnClickListener { +public: + TestSetScreenshotOnClickListener(UIView* uiView) : uiView_(uiView) {} + ~TestSetScreenshotOnClickListener() {} + bool OnClick(UIView& view, const ClickEvent& event) override + { + static_cast(uiView_)->SetSrc("/storage/data/screenshot.bin"); + uiView_->Invalidate(); + return true; + } + +private: + UIView* uiView_; +}; + +void UITestScreenshot::UIKit_SCREENSHOT_TEST_001() +{ + const int16_t titleLableHeight = 29; + const int16_t labelButtonWidth = 80; + const int16_t labelButtonHeight = 40; + if (container_ == nullptr) { + return; + } + UILabel* label = GetTitleLabel("截屏功能测试"); + container_->Add(label); + label->SetPosition(TEXT_DISTANCE_TO_LEFT_SIDE, TEXT_DISTANCE_TO_TOP_SIDE, + Screen::GetInstance().GetWidth() - TEXT_DISTANCE_TO_LEFT_SIDE, titleLableHeight); + UILabelButton* labelButton = SetUpButton("截屏"); + container_->Add(labelButton); + labelButton->SetPosition(210, 50); // 210: position x; 50: position y + labelButton->SetWidth(labelButtonWidth); + labelButton->SetHeight(labelButtonHeight); + labelButton->SetFont(DEFAULT_VECTOR_FONT_FILENAME, BUTTON_LABEL_SIZE); + UIView::OnClickListener* clickLeftListener = new TestScreenshotOnClickListener((UIView*)labelButton); + labelButton->SetOnClickListener(clickLeftListener); + UILabel* label2 = GetTitleLabel("显示截屏图片 "); + container_->Add(label2); + label2->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE, 255, // 255: y-coordinate + Screen::GetInstance().GetWidth() - TEXT_DISTANCE_TO_LEFT_SIDE, titleLableHeight); + UIImageView* imageView = new UIImageView(); + imageView->SetAutoEnable(false); + imageView->SetPosition(0, 290); // 290: y-coordinate + imageView->SetWidth(Screen::GetInstance().GetWidth()); + imageView->SetHeight(Screen::GetInstance().GetHeight() + 100); // 100: increase height + imageView->SetSrc(BLUE_RGB565_IMAGE_PATH); + Style style; + CacheEntry entry; + RetCode ret = CacheManager::GetInstance().Open(imageView->GetPath(), style, entry); + if (ret != RetCode::OK) { + return; + } + container_->Add(imageView); + UILabelButton* labelButton2 = SetUpButton("显示"); + container_->Add(labelButton2); + labelButton2->SetPosition(300, 50); // 300: position x; 50: position y + labelButton2->SetWidth(labelButtonWidth); + labelButton2->SetHeight(labelButtonHeight); + UIView::OnClickListener* clickRightListener = new TestSetScreenshotOnClickListener(static_cast(imageView)); + labelButton2->SetOnClickListener(clickRightListener); +} +} // namespace OHOS +#endif \ No newline at end of file diff --git a/test/uitest/test_screenshot/ui_test_screenshot.h b/test/uitest/test_screenshot/ui_test_screenshot.h new file mode 100755 index 0000000..4934652 --- /dev/null +++ b/test/uitest/test_screenshot/ui_test_screenshot.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef UI_TEST_SCREENSHOT_H +#define UI_TEST_SCREENSHOT_H + +#include "graphic_config.h" +#if ENABLE_DEBUG +#include "components/ui_scroll_view.h" +#include "components/ui_label.h" +#include "components/ui_label_button.h" +#include "dfx/ui_screenshot.h" +#include "ui_test.h" + +namespace OHOS { +class UITestScreenshot : public UITest { +public: + UITestScreenshot() {} + ~UITestScreenshot() {} + void SetUp() override; + void TearDown() override; + UIView* GetTestView() override; + + /** + * @brief Test screenshot Function + */ + void UIKit_SCREENSHOT_TEST_001(); + +private: + UIScrollView* container_ = nullptr; + + UILabelButton* SetUpButton(const char* title) + { + UILabelButton* btn = new UILabelButton(); + btn->SetText(title); + btn->SetFont(DEFAULT_VECTOR_FONT_FILENAME, BUTTON_LABEL_SIZE); + btn->SetStyleForState(STYLE_BORDER_RADIUS, BUTTON_STYLE_BORDER_RADIUS_VALUE, UIButton::RELEASED); + btn->SetStyleForState(STYLE_BORDER_RADIUS, BUTTON_STYLE_BORDER_RADIUS_VALUE, UIButton::PRESSED); + btn->SetStyleForState(STYLE_BORDER_RADIUS, BUTTON_STYLE_BORDER_RADIUS_VALUE, UIButton::INACTIVE); + btn->SetStyleForState(STYLE_BACKGROUND_COLOR, BUTTON_STYLE_BACKGROUND_COLOR_VALUE, UIButton::RELEASED); + btn->SetStyleForState(STYLE_BACKGROUND_COLOR, BUTTON_STYLE_BACKGROUND_COLOR_VALUE, UIButton::PRESSED); + btn->SetStyleForState(STYLE_BACKGROUND_COLOR, BUTTON_STYLE_BACKGROUND_COLOR_VALUE, UIButton::INACTIVE); + return btn; + } +}; // namespace OHOS +} +#endif // ENABLE_DEBUG +#endif // UI_TEST_SCREENSHOT_H \ No newline at end of file diff --git a/test/uitest/test_slider/ui_test_slider.cpp b/test/uitest/test_slider/ui_test_slider.cpp new file mode 100755 index 0000000..06db563 --- /dev/null +++ b/test/uitest/test_slider/ui_test_slider.cpp @@ -0,0 +1,549 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "ui_test_slider.h" +#include "common/screen.h" +#include "test_resource_config.h" + +namespace OHOS { +namespace { +const int16_t LABEL_HEIGHT = 29; +const int16_t BUTTON_WIDTH = 120; +const int16_t BUTTON_HEIGHT = 40; +const int16_t DELTA_X_COORDINATE = 8; +const int16_t DELTA_Y_COORDINATE = 12; +const int16_t DELTA_Y_COORDINATE_2 = 19; +static bool g_onChange = false; +static bool g_onRelease = false; +static bool g_onClick = false; +static bool g_onDrag = false; +static uint16_t g_progress = 20; +static uint16_t g_step = 0; +static uint16_t g_width = 50; +static uint16_t g_height = 250; +static int16_t g_min = 0; +static int16_t g_max = 100; +static int16_t g_knobWidth = 50; +} // namespace + +void TestUISliderEventListener::OnChange(int32_t progress) +{ + value_ = progress; + if (label_ == nullptr) { + if (!MallocLabel()) { + return; + } + } + if (g_onChange) { + label_->SetText("OnChange"); + } +} + +void TestUISliderEventListener::OnRelease(int32_t progress) +{ + value_ = progress; + if (label_ == nullptr) { + if (!MallocLabel()) { + return; + } + } + if (g_onRelease) { + label_->SetText("OnRelease"); + } +} + +bool TestUISliderEventListener::OnClick(UIView& view, const ClickEvent& event) +{ + if (label_ == nullptr) { + if (!MallocLabel()) { + return false; + } + } + if (g_onClick) { + label_->SetText("OnClick"); + } + return true; +} + +bool TestUISliderEventListener::MallocLabel() +{ + label_ = new UILabel(); + if (label_ == nullptr) { + return false; + } + viewGroup_->Add(label_); + label_->SetPosition(0, 0, 100, 30); // 100: width; 30: height + label_->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); + label_->SetStyle(STYLE_TEXT_COLOR, Color::Black().full); + label_->SetStyle(STYLE_BACKGROUND_COLOR, Color::White().full); + label_->SetStyle(STYLE_BACKGROUND_OPA, OPA_OPAQUE); + return true; +} + +bool TestUISliderEventListener::OnDrag(UIView& view, const DragEvent& event) +{ + if (label_ == nullptr) { + if (!MallocLabel()) { + return false; + } + } + + if (g_onDrag) { + label_->SetText("OnDrag"); + } + return true; +} + +void UITestSlider::SetUp() +{ + if (container_ == nullptr) { + container_ = new UIScrollView(); + container_->Resize(Screen::GetInstance().GetWidth(), Screen::GetInstance().GetHeight() - BACK_BUTTON_HEIGHT); + positionX_ = 0; + positionY_ = 0; + UIViewGroup* uiViewGroup = new UIViewGroup(); + uiViewGroup->SetPosition(positionX_, positionY_, 320, 390); // 320: width; 390: height + container_->Add(uiViewGroup); + UILabel* label = new UILabel(); + uiViewGroup->Add(label); + // 288: width; 48: height + label->SetPosition(TEXT_DISTANCE_TO_LEFT_SIDE, TEXT_DISTANCE_TO_TOP_SIDE, 288, 48); + label->SetText("UISlider效果"); + label->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); + uiViewGroupFrame_ = new UIViewGroup(); + uiViewGroup->Add(uiViewGroupFrame_); + // 288: width; 336: height + uiViewGroupFrame_->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE2, VIEW_DISTANCE_TO_TOP_SIDE, 288, 336); + uiViewGroupFrame_->SetStyle(STYLE_BORDER_COLOR, Color::White().full); + uiViewGroupFrame_->SetStyle(STYLE_BORDER_OPA, HALF_OPA_OPAQUE); + uiViewGroupFrame_->SetStyle(STYLE_BORDER_WIDTH, VIEW_STYLE_BORDER_WIDTH); + uiViewGroupFrame_->SetStyle(STYLE_BORDER_RADIUS, VIEW_STYLE_BORDER_RADIUS); + uiViewGroupFrame_->SetStyle(STYLE_BACKGROUND_OPA, 0); + + slider_ = new UISlider(); + slider_->SetPosition(10, 10, 50, 300); // 10:position x; 10: position y; 50: width; 300: height + slider_->SetValidHeight(250); // 250: valid height; + slider_->SetValue(20); // 20: progress bar current value + slider_->SetDirection(UISlider::Direction::DIR_BOTTOM_TO_TOP); + listener_ = new TestUISliderEventListener(uiViewGroupFrame_); + slider_->SetSliderEventListener(listener_); + slider_->SetOnClickListener(listener_); + slider_->SetOnDragListener(listener_); + uiViewGroupFrame_->Add(slider_); + slider_->LayoutCenterOfParent(); + } + + if (scroll_ == nullptr) { + scroll_ = new UIScrollView(); + scroll_->SetPosition(336, 11); // 336: x-coordinate; 11: y-coordinate + scroll_->Resize(624, Screen::GetInstance().GetHeight() - 70); // 624: width; 70: decrease height + container_->Add(scroll_); + positionY_ = 0; + } +} + +void UITestSlider::TearDown() +{ + DeleteChildren(container_); + container_ = nullptr; + slider_ = nullptr; + scroll_ = nullptr; + delete listener_; + listener_ = nullptr; + uiViewGroupFrame_ = nullptr; +} + +UIView* UITestSlider::GetTestView() +{ + UIKit_Slider_Test_UISlider_001(); + UIKit_Slider_Test_SetRange_002(); + UIKit_Slider_Test_SetValue_003(); + UIKit_Slider_Test_SetImage_004(); + UIKit_Slider_Test_SetStyle_005(); + UIKit_Slider_Test_GetStyle_006(); + UIKit_Slider_Test_SetKnobWidth_007(); + UIKit_Slider_Test_SetStep_008(); + UIKit_Slider_Test_SetColor_009(); + UIKit_Slider_Test_SetDirection_010(); + UIKit_Slider_Test_SetValidSize_011(); + UIKit_Slider_Test_SetRadius_012(); + UIKit_Slider_Test_SetOnChangeListener_013(); + UIKit_Slider_Test_SetOnReleaseListener_014(); + UIKit_Slider_Test_SetOnClickCallback_015(); + UIKit_Slider_Test_SetOnDragCallback_016(); + + return container_; +} + +void UITestSlider::SetUpLabel(const char* title, int16_t x, int16_t y) const +{ + UILabel* label = new UILabel(); + scroll_->Add(label); + // 288: width + label->SetPosition(x, y, 288, LABEL_HEIGHT); + label->SetText(title); + label->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); +} +void UITestSlider::SetUpButton(UILabelButton* btn, const char* title, int16_t x, int16_t y) +{ + if (btn == nullptr) { + return; + } + scroll_->Add(btn); + btn->SetPosition(x, y, BUTTON_WIDHT2, BUTTON_HEIGHT2); + btn->SetText(title); + btn->SetFont(DEFAULT_VECTOR_FONT_FILENAME, BUTTON_LABEL_SIZE); + btn->SetOnClickListener(this); + btn->SetStyleForState(STYLE_BORDER_RADIUS, BUTTON_STYLE_BORDER_RADIUS_VALUE, UIButton::RELEASED); + btn->SetStyleForState(STYLE_BORDER_RADIUS, BUTTON_STYLE_BORDER_RADIUS_VALUE, UIButton::PRESSED); + btn->SetStyleForState(STYLE_BORDER_RADIUS, BUTTON_STYLE_BORDER_RADIUS_VALUE, UIButton::INACTIVE); + btn->SetStyleForState(STYLE_BACKGROUND_COLOR, BUTTON_STYLE_BACKGROUND_COLOR_VALUE, UIButton::RELEASED); + btn->SetStyleForState(STYLE_BACKGROUND_COLOR, BUTTON_STYLE_BACKGROUND_COLOR_VALUE, UIButton::PRESSED); + btn->SetStyleForState(STYLE_BACKGROUND_COLOR, BUTTON_STYLE_BACKGROUND_COLOR_VALUE, UIButton::INACTIVE); + scroll_->Invalidate(); +} + +void UITestSlider::UIKit_Slider_Test_UISlider_001() +{ + resetBtn_ = new UILabelButton(); + positionX_ = 24; // 24: x-coordinate + positionY_ = 0; + SetUpLabel("重置Slider:", positionX_, positionY_); + positionY_ += LABEL_HEIGHT + DELTA_X_COORDINATE; + SetUpButton(resetBtn_, "重置", positionX_, positionY_); +} + +void UITestSlider::UIKit_Slider_Test_SetRange_002() +{ + incMinProgressBtn_ = new UILabelButton(); + decMinProgressBtn_ = new UILabelButton(); + incMaxProgressBtn_ = new UILabelButton(); + decMaxProgressBtn_ = new UILabelButton(); + positionX_ = 24; // 24: x-coordinate + positionY_ += BUTTON_HEIGHT + DELTA_Y_COORDINATE_2; + SetUpLabel("设置Slider范围:", positionX_, positionY_); + positionY_ += LABEL_HEIGHT + DELTA_X_COORDINATE; + SetUpButton(incMinProgressBtn_, "下限+", positionX_, positionY_); + positionX_ += BUTTON_WIDTH + DELTA_Y_COORDINATE; + SetUpButton(decMinProgressBtn_, "下限-", positionX_, positionY_); + positionX_ = 24; // 24: x-coordinate + positionY_ += BUTTON_HEIGHT + DELTA_Y_COORDINATE; + SetUpButton(incMaxProgressBtn_, "上限+", positionX_, positionY_); + positionX_ += BUTTON_WIDTH + DELTA_Y_COORDINATE; + SetUpButton(decMaxProgressBtn_, "上限-", positionX_, positionY_); +} + +void UITestSlider::UIKit_Slider_Test_SetValue_003() +{ + incProgressBtn_ = new UILabelButton(); + decProgressBtn_ = new UILabelButton(); + positionX_ = 24; // 24: x-coordinate + positionY_ += BUTTON_HEIGHT + DELTA_Y_COORDINATE_2; + SetUpLabel("设置Slider当前值:", positionX_, positionY_); + positionY_ += LABEL_HEIGHT + DELTA_X_COORDINATE; + SetUpButton(incProgressBtn_, "进度+", positionX_, positionY_); + positionX_ += BUTTON_WIDTH + DELTA_Y_COORDINATE; + SetUpButton(decProgressBtn_, "进度-", positionX_, positionY_); +} + +void UITestSlider::UIKit_Slider_Test_SetImage_004() +{ + imageBtn_ = new UILabelButton(); + noImageBtn_ = new UILabelButton(); + positionX_ = 24; // 24: x-coordinate + positionY_ += BUTTON_HEIGHT + DELTA_Y_COORDINATE_2; + SetUpLabel("Slider设置图片:", positionX_, positionY_); + positionY_ += LABEL_HEIGHT + DELTA_X_COORDINATE; + SetUpButton(imageBtn_, "设置图片", positionX_, positionY_); + positionX_ += BUTTON_WIDTH + DELTA_Y_COORDINATE; + SetUpButton(noImageBtn_, "取消图片", positionX_, positionY_); +} + +void UITestSlider::UIKit_Slider_Test_SetStyle_005() +{ + setStyleBtn_ = new UILabelButton(); + positionX_ = 24; // 24: x-coordinate + positionY_ += BUTTON_HEIGHT + DELTA_Y_COORDINATE_2; + SetUpLabel("Slider设置样式:", positionX_, positionY_); + positionY_ += LABEL_HEIGHT + DELTA_X_COORDINATE; + SetUpButton(setStyleBtn_, "设置样式", positionX_, positionY_); +} + +void UITestSlider::UIKit_Slider_Test_GetStyle_006() +{ + getStyleBtn_ = new UILabelButton(); + positionX_ = 24; // 24: x-coordinate + positionY_ += BUTTON_HEIGHT + DELTA_Y_COORDINATE_2; + SetUpLabel("Slider设置样式:", positionX_, positionY_); + positionY_ += LABEL_HEIGHT + DELTA_X_COORDINATE; + SetUpButton(getStyleBtn_, "设置样式", positionX_, positionY_); +} + +void UITestSlider::UIKit_Slider_Test_SetKnobWidth_007() +{ + incKnobWidthBtn_ = new UILabelButton(); + decKnobWidthBtn_ = new UILabelButton(); + positionX_ = 24; // 24: x-coordinate + positionY_ += BUTTON_HEIGHT + DELTA_Y_COORDINATE_2; + SetUpLabel("设置Slider滑块宽度:", positionX_, positionY_); + positionY_ += LABEL_HEIGHT + DELTA_X_COORDINATE; + SetUpButton(incKnobWidthBtn_, "滑块宽度+", positionX_, positionY_); + positionX_ += BUTTON_WIDTH + DELTA_Y_COORDINATE; + SetUpButton(decKnobWidthBtn_, "滑块宽度-", positionX_, positionY_); +} + +void UITestSlider::UIKit_Slider_Test_SetStep_008() +{ + stepBtn_ = new UILabelButton(); + positionX_ = 24; // 24: x-coordinate + positionY_ += BUTTON_HEIGHT + DELTA_Y_COORDINATE_2; + SetUpLabel("设置Slider步长:", positionX_, positionY_); + positionY_ += LABEL_HEIGHT + DELTA_X_COORDINATE; + SetUpButton(stepBtn_, "步长+", positionX_, positionY_); +} + +void UITestSlider::UIKit_Slider_Test_SetColor_009() +{ + colorBtn_ = new UILabelButton(); + positionX_ = 336; // 336: x-coordinate + positionY_ = 0; + SetUpLabel("设置Slider颜色:", positionX_, positionY_); + positionY_ += LABEL_HEIGHT + DELTA_X_COORDINATE; + SetUpButton(colorBtn_, "设置颜色", positionX_, positionY_); +} + +void UITestSlider::UIKit_Slider_Test_SetDirection_010() +{ + dirL2RBtn_ = new UILabelButton(); + dirR2LBtn_ = new UILabelButton(); + dirT2BBtn_ = new UILabelButton(); + dirB2TBtn_ = new UILabelButton(); + positionX_ = 336; // 336: x-coordinate + positionY_ += BUTTON_HEIGHT + DELTA_Y_COORDINATE_2; + SetUpLabel("设置Slider方向:", positionX_, positionY_); + positionY_ += LABEL_HEIGHT + DELTA_X_COORDINATE; + SetUpButton(dirL2RBtn_, "从左到右", positionX_, positionY_); + positionX_ += BUTTON_WIDTH + DELTA_Y_COORDINATE; + SetUpButton(dirR2LBtn_, "从右到左", positionX_, positionY_); + positionX_ = 336; // 336: x-coordinate + positionY_ += BUTTON_HEIGHT + DELTA_Y_COORDINATE; + SetUpButton(dirT2BBtn_, "从上到下", positionX_, positionY_); + positionX_ += BUTTON_WIDTH + DELTA_Y_COORDINATE; + SetUpButton(dirB2TBtn_, "从下到上", positionX_, positionY_); +} + +void UITestSlider::UIKit_Slider_Test_SetValidSize_011() +{ + widthBtn_ = new UILabelButton(); + heightBtn_ = new UILabelButton(); + positionX_ = 336; // 336: x-coordinate + positionY_ += BUTTON_HEIGHT + DELTA_Y_COORDINATE_2; + SetUpLabel("设置Slider有效区域宽高:", positionX_, positionY_); + positionY_ += LABEL_HEIGHT + DELTA_X_COORDINATE; + SetUpButton(heightBtn_, "box高度 ", positionX_, positionY_); + positionX_ += BUTTON_WIDTH + DELTA_Y_COORDINATE; + SetUpButton(widthBtn_, "box宽度 ", positionX_, positionY_); +} + +void UITestSlider::UIKit_Slider_Test_SetRadius_012() +{ + radiusBtn_ = new UILabelButton(); + positionX_ = 336; // 336: x-coordinate + positionY_ += BUTTON_HEIGHT + DELTA_Y_COORDINATE_2; + SetUpLabel("设置lider圆角弧度:", positionX_, positionY_); + positionY_ += LABEL_HEIGHT + DELTA_X_COORDINATE; + SetUpButton(radiusBtn_, "圆角弧度", positionX_, positionY_); +} + +void UITestSlider::UIKit_Slider_Test_SetOnChangeListener_013() +{ + onChangeBtn_ = new UILabelButton(); + positionX_ = 336; // 336: x-coordinate + positionY_ += BUTTON_HEIGHT + DELTA_Y_COORDINATE_2; + SetUpLabel("Slider设置点击和滑动监听: ", positionX_, positionY_); + positionY_ += LABEL_HEIGHT + DELTA_X_COORDINATE; + SetUpButton(onChangeBtn_, "OnChange", positionX_, positionY_); +} + +void UITestSlider::UIKit_Slider_Test_SetOnReleaseListener_014() +{ + onReleaseBtn_ = new UILabelButton(); + positionX_ = 336; // 336: x-coordinate + positionY_ += BUTTON_HEIGHT + DELTA_Y_COORDINATE_2; + SetUpLabel("Slider设置滑动结束监听:", positionX_, positionY_); + positionY_ += LABEL_HEIGHT + DELTA_X_COORDINATE; + SetUpButton(onReleaseBtn_, "OnRelease", positionX_, positionY_); +} + +void UITestSlider::UIKit_Slider_Test_SetOnClickCallback_015() +{ + onClickBtn_ = new UILabelButton(); + positionX_ = 336; // 336: x-coordinate + positionY_ += BUTTON_HEIGHT + DELTA_Y_COORDINATE_2; + SetUpLabel("Slider设置点击事件回调:", positionX_, positionY_); + positionY_ += LABEL_HEIGHT + DELTA_X_COORDINATE; + SetUpButton(onClickBtn_, "OnClick回调", positionX_, positionY_); +} + +void UITestSlider::UIKit_Slider_Test_SetOnDragCallback_016() +{ + onDragBtn_ = new UILabelButton(); + positionX_ = 336; // 336: x-coordinate + positionY_ += BUTTON_HEIGHT + DELTA_Y_COORDINATE_2; + SetUpLabel("Slider设置滑动事件回调:", positionX_, positionY_); + positionY_ += LABEL_HEIGHT + DELTA_X_COORDINATE; + SetUpButton(onDragBtn_, "OnDrag回调", positionX_, positionY_); +} +bool UITestSlider::OnClick(UIView& view, const ClickEvent& event) +{ + g_progress = 20; // 20: progress + g_step = 0; + g_width = 50; // 50: width + g_height = 250; // 250: height + g_min = 0; + g_max = 100; // 100: max + g_knobWidth = 50; // 50: knobWidth + if (&view == resetBtn_) { + slider_->LayoutCenterOfParent(); + g_progress = 20; // 20: progress + g_step = 0; + g_width = 50; // 50: width + g_height = 250; // 250: height + g_knobWidth = 50; // 50: knobWidth + g_min = 0; + g_max = 100; // 100: max + slider_->SetDirection(UISlider::Direction::DIR_BOTTOM_TO_TOP); + slider_->SetValidHeight(g_height); + slider_->SetValidWidth(g_width); + slider_->SetKnobWidth(50); // 50: knob width + slider_->SetRange(g_max, g_min); + slider_->SetValue(g_progress); + slider_->SetStep(g_step); + slider_->SetBackgroundStyle(StyleDefault::GetProgressBackgroundStyle()); + slider_->SetForegroundStyle(StyleDefault::GetProgressForegroundStyle()); + slider_->SetKnobStyle(StyleDefault::GetSliderKnobStyle()); + slider_->SetImage(static_cast(nullptr), static_cast(nullptr), + static_cast(nullptr)); + slider_->EnableBackground(true); + } else if (&view == incProgressBtn_) { + g_progress++; + slider_->SetValue(g_progress); + } else if (&view == decProgressBtn_) { + g_progress--; + slider_->SetValue(g_progress); + } else if (&view == stepBtn_) { + g_step++; + slider_->SetStep(g_step); + } else { + ExpandClick1(view, event); + } + container_->Invalidate(); + return true; +} + +bool UITestSlider::ExpandClick1(UIView& view, const ClickEvent& event) +{ + if (&view == widthBtn_) { + g_width--; + slider_->SetValidWidth(g_width); + } else if (&view == heightBtn_) { + g_height--; + slider_->SetValidHeight(g_height); + } else if (&view == incMinProgressBtn_) { + g_min++; + slider_->SetRange(slider_->GetRangeMax(), g_min); + } else if (&view == decMinProgressBtn_) { + g_min--; + slider_->SetRange(slider_->GetRangeMax(), g_min); + } else if (&view == incMaxProgressBtn_) { + g_max++; + slider_->SetRange(g_max, slider_->GetRangeMin()); + } else if (&view == decMaxProgressBtn_) { + g_max--; + slider_->SetRange(g_max, slider_->GetRangeMin()); + } else if (&view == dirL2RBtn_) { + g_width = DEFAULT_HEIGHT; + g_height = DEFAULT_WIDTH; + slider_->Resize(g_width, g_height); + slider_->SetDirection(UISlider::Direction::DIR_LEFT_TO_RIGHT); + } else if (&view == dirR2LBtn_) { + g_width = DEFAULT_HEIGHT; + g_height = DEFAULT_WIDTH; + slider_->Resize(g_width, g_height); + slider_->SetDirection(UISlider::Direction::DIR_RIGHT_TO_LEFT); + } else if (&view == dirT2BBtn_) { + g_width = DEFAULT_WIDTH; + g_height = DEFAULT_HEIGHT; + slider_->Resize(g_width, g_height); + slider_->SetDirection(UISlider::Direction::DIR_TOP_TO_BOTTOM); + } else if (&view == dirB2TBtn_) { + g_width = DEFAULT_WIDTH; + g_height = DEFAULT_HEIGHT; + slider_->Resize(g_width, g_height); + slider_->SetDirection(UISlider::Direction::DIR_BOTTOM_TO_TOP); + } else { + ExpandClick2(view, event); + } + return true; +} + +bool UITestSlider::ExpandClick2(UIView& view, const ClickEvent& event) +{ + if (&view == imageBtn_) { + slider_->SetValidHeight(DEFAULT_HEIGHT); + slider_->SetValidWidth(5); // 5 valid width + slider_->SetKnobWidth(40); // 40: knob width + slider_->SetDirection(UISlider::Direction::DIR_BOTTOM_TO_TOP); + slider_->SetImage(SLIDER_BACKGROUND_IMAGE_PATH, SLIDER_INDICATOR_IMAGE_PATH, SLIDER_KNOB_IMAGE_PATH); + } else if (&view == noImageBtn_) { + slider_->SetValidHeight(g_height); + slider_->SetValidWidth(g_width); + slider_->SetKnobWidth(g_knobWidth); + slider_->SetImage(static_cast(nullptr), static_cast(nullptr), + static_cast(nullptr)); + } else if (&view == setStyleBtn_) { + Style style = StyleDefault::GetDefaultStyle(); + style.bgColor_ = Color::White(); + slider_->SetBackgroundStyle(style); + style.bgColor_ = Color::Blue(); + slider_->SetForegroundStyle(style); + style.bgColor_ = Color::Gray(); + slider_->SetKnobStyle(style); + } else if (&view == getStyleBtn_) { + slider_->SetBackgroundStyle(STYLE_BACKGROUND_COLOR, Color::Red().full); + slider_->SetForegroundStyle(STYLE_BACKGROUND_COLOR, Color::Yellow().full); + slider_->SetKnobStyle(STYLE_BACKGROUND_COLOR, Color::Green().full); + } else if (&view == incKnobWidthBtn_) { + g_knobWidth++; + slider_->SetKnobWidth(g_knobWidth); + } else if (&view == decKnobWidthBtn_) { + g_knobWidth--; + slider_->SetKnobWidth(g_knobWidth); + } else if (&view == colorBtn_) { + slider_->SetSliderColor(Color::Silver(), Color::Blue(), Color::White()); + } else if (&view == radiusBtn_) { + slider_->SetSliderRadius(DEFAULT_RADIUS, DEFAULT_RADIUS, DEFAULT_RADIUS); + } else if (&view == onChangeBtn_) { + g_onChange = true; + } else if (&view == onReleaseBtn_) { + g_onRelease = true; + } else if (&view == onClickBtn_) { + g_onClick = true; + } else if (&view == onDragBtn_) { + g_onDrag = true; + } + return true; +} +} // namespace OHOS \ No newline at end of file diff --git a/test/uitest/test_slider/ui_test_slider.h b/test/uitest/test_slider/ui_test_slider.h new file mode 100755 index 0000000..121bc7d --- /dev/null +++ b/test/uitest/test_slider/ui_test_slider.h @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef UI_TEST_SLIDER_H +#define UI_TEST_SLIDER_H + +#include "components/ui_label.h" +#include "components/ui_label_button.h" +#include "components/ui_scroll_view.h" +#include "components/ui_slider.h" +#include "ui_test.h" + +namespace OHOS { +class TestUISliderEventListener : public UISlider::UISliderEventListener, + public UIView::OnClickListener, + public UIView::OnDragListener { +public: + explicit TestUISliderEventListener(UIViewGroup* viewGroup) + { + viewGroup_ = viewGroup; + } + virtual ~TestUISliderEventListener() {} + void OnChange(int32_t progress) override; + void OnRelease(int32_t progress) override; + bool OnClick(UIView& view, const ClickEvent& event) override; + bool OnDrag(UIView& view, const DragEvent& event) override; + bool MallocLabel(); + +private: + UILabel* label_ = nullptr; + UIViewGroup* viewGroup_ = nullptr; + int32_t value_ = 0; +}; + +class UITestSlider : public UITest, public UIView::OnClickListener { +public: + UITestSlider() {} + ~UITestSlider() {} + void SetUp() override; + void TearDown() override; + UIView* GetTestView() override; + + void SetUpButton(UILabelButton* btn, const char* title, int16_t x, int16_t y); + void SetUpLabel(const char* title, int16_t x, int16_t y) const; + + bool OnClick(UIView& view, const ClickEvent& event) override; + bool ExpandClick1(UIView& view, const ClickEvent& event); + bool ExpandClick2(UIView& view, const ClickEvent& event); + + void UIKit_Slider_Test_UISlider_001(); + void UIKit_Slider_Test_SetRange_002(); + void UIKit_Slider_Test_SetValue_003(); + void UIKit_Slider_Test_SetImage_004(); + void UIKit_Slider_Test_SetStyle_005(); + void UIKit_Slider_Test_GetStyle_006(); + void UIKit_Slider_Test_SetKnobWidth_007(); + void UIKit_Slider_Test_SetStep_008(); + void UIKit_Slider_Test_SetColor_009(); + void UIKit_Slider_Test_SetDirection_010(); + void UIKit_Slider_Test_SetValidSize_011(); + void UIKit_Slider_Test_SetRadius_012(); + void UIKit_Slider_Test_SetOnChangeListener_013(); + void UIKit_Slider_Test_SetOnReleaseListener_014(); + void UIKit_Slider_Test_SetOnClickCallback_015(); + void UIKit_Slider_Test_SetOnDragCallback_016(); + +private: + static constexpr int32_t DEFAULT_VALUE = 20; + static constexpr int16_t DEFAULT_WIDTH = 50; + static constexpr int16_t DEFAULT_HEIGHT = 250; + static constexpr int16_t DEFAULT_RADIUS = 10; + static constexpr int32_t MAX_VALUE = 100; + UIScrollView* container_ = nullptr; + UIScrollView* scroll_ = nullptr; + UISlider* slider_ = nullptr; + TestUISliderEventListener* listener_ = nullptr; + UIViewGroup* uiViewGroupFrame_ = nullptr; + + UILabelButton* resetBtn_ = nullptr; + UILabelButton* widthBtn_ = nullptr; + UILabelButton* heightBtn_ = nullptr; + UILabelButton* incProgressBtn_ = nullptr; + UILabelButton* decProgressBtn_ = nullptr; + UILabelButton* incMinProgressBtn_ = nullptr; + UILabelButton* decMinProgressBtn_ = nullptr; + UILabelButton* incMaxProgressBtn_ = nullptr; + UILabelButton* decMaxProgressBtn_ = nullptr; + UILabelButton* stepBtn_ = nullptr; + UILabelButton* dirL2RBtn_ = nullptr; + UILabelButton* dirR2LBtn_ = nullptr; + UILabelButton* dirT2BBtn_ = nullptr; + UILabelButton* dirB2TBtn_ = nullptr; + UILabelButton* imageBtn_ = nullptr; + UILabelButton* noImageBtn_ = nullptr; + UILabelButton* setStyleBtn_ = nullptr; + UILabelButton* getStyleBtn_ = nullptr; + UILabelButton* incKnobWidthBtn_ = nullptr; + UILabelButton* decKnobWidthBtn_ = nullptr; + UILabelButton* colorBtn_ = nullptr; + UILabelButton* radiusBtn_ = nullptr; + UILabelButton* onChangeBtn_ = nullptr; + UILabelButton* onReleaseBtn_ = nullptr; + UILabelButton* onClickBtn_ = nullptr; + UILabelButton* onDragBtn_ = nullptr; +}; +} // namespace OHOS +#endif // UI_TEST_SLIDER_H diff --git a/test/uitest/test_texture_mapper/ui_test_texture_mapper.cpp b/test/uitest/test_texture_mapper/ui_test_texture_mapper.cpp new file mode 100755 index 0000000..685dbba --- /dev/null +++ b/test/uitest/test_texture_mapper/ui_test_texture_mapper.cpp @@ -0,0 +1,273 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "ui_test_texture_mapper.h" +#include "common/screen.h" +#include "test_resource_config.h" + +namespace OHOS { +namespace { +static int16_t g_rotateStart = 0; // 0: the start angle of rotation +static int16_t g_rotateEnd = 360; // 360: the end angle of rotation +static float g_scaleStart = 1; // 1: the start ratio +static float g_scaleEnd = 0.5; // 0.5: the end ratio +static uint16_t g_durationTime = 2000; // 2000: the duration for this animator +static uint16_t g_delayTime = 0; +static EasingFunc g_easingFunc = EasingEquation::CubicEaseInOut; +static Point g_pivot = {58, 58}; // 58: the x-coordinate,; 58: the y-coordinate +} // namespace + +void UITestTextureMapper::SetUp() +{ + if (container_ == nullptr) { + container_ = new UIScrollView(); + container_->Resize(Screen::GetInstance().GetWidth(), Screen::GetInstance().GetHeight() - BACK_BUTTON_HEIGHT); + UIViewGroup* uiViewGroup = new UIViewGroup(); + uiViewGroup->SetPosition(0, 0, 320, 390); // 320: width; 390: height + container_->Add(uiViewGroup); + UILabel* label = new UILabel(); + uiViewGroup->Add(label); + // 288: x-coordinate; 48: y-coordinate + label->SetPosition(TEXT_DISTANCE_TO_LEFT_SIDE, TEXT_DISTANCE_TO_TOP_SIDE, 288, 48); + label->SetText("UITextureMapper效果"); + label->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); + UIViewGroup* uiViewGroupFrame = new UIViewGroup(); + uiViewGroup->Add(uiViewGroupFrame); + // 288: x-coordinate; 336: y-coordinate + uiViewGroupFrame->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE2, VIEW_DISTANCE_TO_TOP_SIDE, 288, 336); + uiViewGroupFrame->SetStyle(STYLE_BORDER_COLOR, Color::White().full); + uiViewGroupFrame->SetStyle(STYLE_BORDER_OPA, HALF_OPA_OPAQUE); + uiViewGroupFrame->SetStyle(STYLE_BORDER_WIDTH, VIEW_STYLE_BORDER_WIDTH); + uiViewGroupFrame->SetStyle(STYLE_BORDER_RADIUS, VIEW_STYLE_BORDER_RADIUS); + uiViewGroupFrame->SetStyle(STYLE_BACKGROUND_OPA, 0); + textureMapper_ = new UITextureMapper(); + textureMapper_->SetPosition(200, 50, 200, 200); // 200:position x; 50: positon y; 200: width; 200: height + textureMapper_->SetSrc(RED_IMAGE_PATH); + textureMapper_->SetRotateStart(0); + textureMapper_->SetRotateEnd(360); // 360: the end angle of rotation + textureMapper_->SetScaleStart(1); // 1: the start ratio + textureMapper_->SetScaleEnd(0.5); // 0.5: the end ratio + textureMapper_->SetPivot(58, 58); // 58: the x-coordinate,; 58: the y-coordinate + textureMapper_->SetDurationTime(2000); // 2000: the duration for this animator + listener_ = new TestTextureMapperStopListener(uiViewGroupFrame); + uiViewGroupFrame->Add(textureMapper_); + textureMapper_->LayoutCenterOfParent(); + } + if (layout_ == nullptr) { + layout_ = new GridLayout(); + layout_->SetPosition(336, 48, 516, 232); // 336: x-coordinate; 48: y-coordinate; 516: y value; 232: height + container_->Add(layout_); + layout_->SetLayoutDirection(LAYOUT_HOR); + layout_->SetRows(4); // 4: the number of rows + layout_->SetCols(4); // 4: the number of columns + } + resetBtn_ = new UILabelButton(); + SetUpButton(resetBtn_, "重置"); +} + +void UITestTextureMapper::TearDown() +{ + DeleteChildren(container_); + container_ = nullptr; + textureMapper_ = nullptr; + layout_ = nullptr; + delete listener_; + listener_ = nullptr; +} + +UIView* UITestTextureMapper::GetTestView() +{ + UIKit_TextureMapper_Test_SetRotateEnd_001(); + UIKit_TextureMapper_Test_SetRotateStart_002(); + UIKit_TextureMapper_Test_SetScaleEnd_003(); + UIKit_TextureMapper_Test_SetScaleStart_004(); + UIKit_TextureMapper_Test_SetPivot_005(); + UIKit_TextureMapper_Test_Start_006(); + UIKit_TextureMapper_Test_Reset_007(); + UIKit_TextureMapper_Test_CancelAnimation_008(); + UIKit_TextureMapper_Test_SetAnimatorStopListener_009(); + + layout_->LayoutChildren(); + return container_; +} + +void UITestTextureMapper::SetUpButton(UILabelButton* btn, const char* title) +{ + if (btn == nullptr) { + return; + } + layout_->Add(btn); + btn->Resize(BUTTON_WIDHT2, BUTTON_HEIGHT2); + btn->SetText(title); + btn->SetFont(DEFAULT_VECTOR_FONT_FILENAME, BUTTON_LABEL_SIZE); + btn->SetOnClickListener(this); + btn->SetStyleForState(STYLE_BORDER_RADIUS, BUTTON_STYLE_BORDER_RADIUS_VALUE, UIButton::RELEASED); + btn->SetStyleForState(STYLE_BORDER_RADIUS, BUTTON_STYLE_BORDER_RADIUS_VALUE, UIButton::PRESSED); + btn->SetStyleForState(STYLE_BORDER_RADIUS, BUTTON_STYLE_BORDER_RADIUS_VALUE, UIButton::INACTIVE); + btn->SetStyleForState(STYLE_BACKGROUND_COLOR, BUTTON_STYLE_BACKGROUND_COLOR_VALUE, UIButton::RELEASED); + btn->SetStyleForState(STYLE_BACKGROUND_COLOR, BUTTON_STYLE_BACKGROUND_COLOR_VALUE, UIButton::PRESSED); + btn->SetStyleForState(STYLE_BACKGROUND_COLOR, BUTTON_STYLE_BACKGROUND_COLOR_VALUE, UIButton::INACTIVE); +} + +void UITestTextureMapper::UIKit_TextureMapper_Test_SetRotateEnd_001() +{ + incRotateEndBtn_ = new UILabelButton(); + SetUpButton(incRotateEndBtn_, "旋转结束角度+"); + + decRotateEndBtn_ = new UILabelButton(); + SetUpButton(decRotateEndBtn_, "旋转结束角度-"); +} + +void UITestTextureMapper::UIKit_TextureMapper_Test_SetRotateStart_002() +{ + startAngleBtn_ = new UILabelButton(); + SetUpButton(startAngleBtn_, "旋转起始角度+"); +} + +void UITestTextureMapper::UIKit_TextureMapper_Test_SetScaleEnd_003() +{ + incScaleEndBtn_ = new UILabelButton(); + SetUpButton(incScaleEndBtn_, "缩放结束比例+"); + + decScaleEndBtn_ = new UILabelButton(); + SetUpButton(decScaleEndBtn_, "缩放结束比例-"); +} + +void UITestTextureMapper::UIKit_TextureMapper_Test_SetScaleStart_004() +{ + startScaleBtn_ = new UILabelButton(); + SetUpButton(startScaleBtn_, "缩放起始比例+"); +} + +void UITestTextureMapper::UIKit_TextureMapper_Test_SetPivot_005() +{ + incPivotBtn_ = new UILabelButton(); + SetUpButton(incPivotBtn_, "中心+"); + + decPivotBtn_ = new UILabelButton(); + SetUpButton(decPivotBtn_, "中心-"); + + durationTimeBtn_ = new UILabelButton(); + SetUpButton(durationTimeBtn_, "持续时间+"); + + delayTimeBtn_ = new UILabelButton(); + SetUpButton(delayTimeBtn_, "延时时间+"); + + easingBtn_ = new UILabelButton(); + SetUpButton(easingBtn_, "动效"); +} + +void UITestTextureMapper::UIKit_TextureMapper_Test_Start_006() +{ + startBtn_ = new UILabelButton(); + SetUpButton(startBtn_, "启动动画"); +} + +void UITestTextureMapper::UIKit_TextureMapper_Test_Reset_007() +{ + resetImageBtn_ = new UILabelButton(); + SetUpButton(resetImageBtn_, "显示原始图片"); +} + +void UITestTextureMapper::UIKit_TextureMapper_Test_CancelAnimation_008() +{ + cancelBtn_ = new UILabelButton(); + SetUpButton(cancelBtn_, "取消动画 "); +} + +void UITestTextureMapper::UIKit_TextureMapper_Test_SetAnimatorStopListener_009() +{ + listenerBtn_ = new UILabelButton(); + SetUpButton(listenerBtn_, "动画结束监听"); +} + +bool UITestTextureMapper::OnClick(UIView& view, const ClickEvent& event) +{ + g_rotateStart = 0; // 0: the start angle of rotation + g_rotateEnd = 360; // 360: the end angle of rotation + g_scaleStart = 1; // 1: the start ratio + g_scaleEnd = 0.5; // 0.5: the end ratio + g_durationTime = 2000; // 2000: the duration for this animator + g_delayTime = 0; + g_easingFunc = EasingEquation::CubicEaseInOut; + if (&view == resetBtn_) { + g_rotateStart = 0; // 0: the start angle of rotation + g_rotateEnd = 360; // 360: the end angle of rotation + g_scaleStart = 1; // 1: the start ratio + g_scaleEnd = 0.5; // 0.5: the end ratio + + g_durationTime = 2000; // 2000: the duration for this animator + g_delayTime = 0; + g_easingFunc = EasingEquation::CubicEaseInOut; + g_pivot = {58, 58}; // 58: the x-coordinate,; 58: the y-coordinate + textureMapper_->SetRotateStart(g_rotateStart); + textureMapper_->SetScaleStart(g_scaleStart); + textureMapper_->SetPivot(g_pivot.x, g_pivot.y); + textureMapper_->Reset(); + } else if (&view == incRotateEndBtn_) { + g_rotateEnd += 90; // 90: the end angle of rotation augmentation + textureMapper_->SetRotateEnd(g_rotateEnd); + } else if (&view == decRotateEndBtn_) { + g_rotateEnd -= 90; // 90: the end angle of rotation decrease + textureMapper_->SetRotateEnd(g_rotateEnd); + } else if (&view == durationTimeBtn_) { + g_durationTime += 200; // 200: the duration for this animator augmentation + textureMapper_->SetDurationTime(g_durationTime); + } else if (&view == delayTimeBtn_) { + g_delayTime += 200; // 200: the delay for this animator augmentation + textureMapper_->SetDelayTime(g_delayTime); + } else if (&view == easingBtn_) { + g_easingFunc = EasingEquation::SineEaseIn; + textureMapper_->SetEasingFunc(g_easingFunc); + } else if (&view == startAngleBtn_) { + g_rotateStart += 90; // 90: the start angle of rotation augmentation + textureMapper_->SetRotateStart(g_rotateStart); + } else { + ExpandClick(view, event); + } + return true; +} + +bool UITestTextureMapper::ExpandClick(UIView& view, const ClickEvent& event) +{ + if (&view == incScaleEndBtn_) { + g_scaleEnd += 0.2; // 0.2: the end ratio augmentation + textureMapper_->SetScaleEnd(g_scaleEnd); + } else if (&view == decScaleEndBtn_) { + g_scaleEnd -= 0.2; // 0.2: the end ratio decrease + textureMapper_->SetScaleEnd(g_scaleEnd); + } else if (&view == startScaleBtn_) { + g_scaleStart += 0.2; // 0.2: the start ratio augmentation + textureMapper_->SetScaleStart(g_scaleStart); + } else if (&view == incPivotBtn_) { + g_pivot.x += 5; // 5: pivot offset pixel + g_pivot.y += 5; // 5: pivot offset pixel + textureMapper_->SetPivot(g_pivot.x, g_pivot.y); + } else if (&view == decPivotBtn_) { + g_pivot.x -= 5; // 5: pivot offset pixel + g_pivot.y -= 5; // 5: pivot offset pixel + textureMapper_->SetPivot(g_pivot.x, g_pivot.y); + } else if (&view == startBtn_) { + textureMapper_->Start(); + } else if (&view == resetImageBtn_) { + textureMapper_->Reset(); + } else if (&view == cancelBtn_) { + textureMapper_->Cancel(); + } else if (&view == listenerBtn_) { + textureMapper_->SetAnimatorStopListener(listener_); + } + return true; +} +} // namespace OHOS \ No newline at end of file diff --git a/test/uitest/test_texture_mapper/ui_test_texture_mapper.h b/test/uitest/test_texture_mapper/ui_test_texture_mapper.h new file mode 100755 index 0000000..a56037a --- /dev/null +++ b/test/uitest/test_texture_mapper/ui_test_texture_mapper.h @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef UI_TEST_TEXTURE_MAPPER_H +#define UI_TEST_TEXTURE_MAPPER_H + +#include "components/ui_label.h" +#include "components/ui_label_button.h" +#include "components/ui_scroll_view.h" +#include "components/ui_texture_mapper.h" +#include "layout/grid_layout.h" +#include "ui_test.h" + +namespace OHOS { +class TestTextureMapperStopListener : public UITextureMapper::AnimatorStopListener { +public: + explicit TestTextureMapperStopListener(UIViewGroup* viewGroup) + { + if (viewGroup != nullptr) { + viewGroup_ = viewGroup; + label_ = new UILabel(); + viewGroup_->Add(label_); + label_->SetPosition(0, 0, 200, TITLE_LABEL_DEFAULT_HEIGHT); // 200: width; + label_->SetText("OnAnimatorStop"); + label_->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); + label_->SetStyle(STYLE_TEXT_COLOR, Color::Black().full); + label_->SetStyle(STYLE_BACKGROUND_COLOR, Color::White().full); + label_->SetStyle(STYLE_BACKGROUND_OPA, OPA_OPAQUE); + label_->SetVisible(false); + } + } + + ~TestTextureMapperStopListener() {}; + + void OnAnimatorStop(UIView& view) override + { + label_->SetVisible(true); + label_->Invalidate(); + } +private: + UILabel* label_ = nullptr; + UIViewGroup* viewGroup_ = nullptr; +}; + +class UITestTextureMapper : public UITest, public UIView::OnClickListener { +public: + UITestTextureMapper() {} + ~UITestTextureMapper() {}; + void SetUp() override; + void TearDown() override; + UIView* GetTestView() override; + + void SetUpButton(UILabelButton* btn, const char* title); + + bool OnClick(UIView& view, const ClickEvent& event) override; + bool ExpandClick(UIView& view, const ClickEvent& event); + + void UIKit_TextureMapper_Test_SetRotateEnd_001(); + void UIKit_TextureMapper_Test_SetRotateStart_002(); + void UIKit_TextureMapper_Test_SetScaleEnd_003(); + void UIKit_TextureMapper_Test_SetScaleStart_004(); + void UIKit_TextureMapper_Test_SetPivot_005(); + void UIKit_TextureMapper_Test_Start_006(); + void UIKit_TextureMapper_Test_Reset_007(); + void UIKit_TextureMapper_Test_CancelAnimation_008(); + void UIKit_TextureMapper_Test_SetAnimatorStopListener_009(); + +private: + UIScrollView* container_ = nullptr; + GridLayout* layout_ = nullptr; + UITextureMapper* textureMapper_ = nullptr; + TestTextureMapperStopListener* listener_ = nullptr; + + UILabelButton* resetBtn_ = nullptr; + + UILabelButton* incRotateEndBtn_ = nullptr; + UILabelButton* decRotateEndBtn_ = nullptr; + UILabelButton* startAngleBtn_ = nullptr; + + UILabelButton* incScaleEndBtn_ = nullptr; + UILabelButton* decScaleEndBtn_ = nullptr; + UILabelButton* startScaleBtn_ = nullptr; + + UILabelButton* durationTimeBtn_ = nullptr; + UILabelButton* delayTimeBtn_ = nullptr; + UILabelButton* easingBtn_ = nullptr; + + UILabelButton* incPivotBtn_ = nullptr; + UILabelButton* decPivotBtn_ = nullptr; + UILabelButton* startBtn_ = nullptr; + UILabelButton* cancelBtn_ = nullptr; + UILabelButton* resetImageBtn_ = nullptr; + UILabelButton* listenerBtn_ = nullptr; +}; +} // namespace OHOS +#endif // UI_TEST_TEXTURE_MAPPER_H diff --git a/test/uitest/test_transform/ui_test_transform.cpp b/test/uitest/test_transform/ui_test_transform.cpp new file mode 100755 index 0000000..61d0753 --- /dev/null +++ b/test/uitest/test_transform/ui_test_transform.cpp @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "ui_test_transform.h" +#include "common/screen.h" +#include "test_resource_config.h" + +namespace OHOS { +void UITestTransform::SetUp() +{ + if (container_ == nullptr) { + container_ = new UIScrollView(); + container_->Resize(Screen::GetInstance().GetWidth(), Screen::GetInstance().GetHeight() - BACK_BUTTON_HEIGHT); + UIViewGroup* uiViewGroup = new UIViewGroup(); + uiViewGroup->SetPosition(0, 0, 320, 390); // 320: width; 390: height + container_->Add(uiViewGroup); + UILabel* label = new UILabel(); + uiViewGroup->Add(label); + // 288: width; 48: height + label->SetPosition(TEXT_DISTANCE_TO_LEFT_SIDE, TEXT_DISTANCE_TO_TOP_SIDE, 288, 48); + label->SetText("UITransform效果"); + label->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); + uiViewGroupFrame_ = new UIViewGroup(); + uiViewGroup->Add(uiViewGroupFrame_); + // 288: width; 336: height + uiViewGroupFrame_->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE2, VIEW_DISTANCE_TO_TOP_SIDE, 288, 336); + uiViewGroupFrame_->SetStyle(STYLE_BORDER_COLOR, Color::White().full); + uiViewGroupFrame_->SetStyle(STYLE_BORDER_OPA, HALF_OPA_OPAQUE); + uiViewGroupFrame_->SetStyle(STYLE_BORDER_WIDTH, VIEW_STYLE_BORDER_WIDTH); + uiViewGroupFrame_->SetStyle(STYLE_BORDER_RADIUS, VIEW_STYLE_BORDER_RADIUS); + uiViewGroupFrame_->SetStyle(STYLE_BACKGROUND_OPA, 0); + + imageView_ = new UIImageView(); + imageView_->SetPosition(150, 50, 200, 200); // 150:poistion x 50:position y 200:width 200:height + imageView_->SetSrc(BLUE_IMAGE_PATH); + uiViewGroupFrame_->Add(imageView_); + imageView_->LayoutCenterOfParent(); + } + + if (layout_ == nullptr) { + layout_ = new GridLayout(); + // 34: increase x-coordinate; 48: y-coordinate; 100: width; 150: height + layout_->SetPosition(uiViewGroupFrame_->GetWidth() + 34, 48, 100, 150); + container_->Add(layout_); + layout_->SetLayoutDirection(LAYOUT_VER); + layout_->SetRows(3); // 3:two rows + layout_->SetCols(1); // 1:three cols + } +} + +void UITestTransform::TearDown() +{ + DeleteChildren(container_); + container_ = nullptr; + layout_ = nullptr; + uiViewGroupFrame_ = nullptr; + imageView_ = nullptr; +} + +UIView* UITestTransform::GetTestView() +{ + UIKit_Transform_Test_Rotate_001(); + UIKit_Transform_Test_Scale_002(); + UIKit_Transform_Test_Translate_003(); + + layout_->LayoutChildren(); + return container_; +} + +void UITestTransform::SetUpButton(UILabelButton* btn, const char* title) +{ + if (btn == nullptr) { + return; + } + layout_->Add(btn); + btn->Resize(BUTTON_WIDHT1, BUTTON_HEIGHT1); + btn->SetText(title); + btn->SetFont(DEFAULT_VECTOR_FONT_FILENAME, BUTTON_LABEL_SIZE); + btn->SetOnClickListener(this); + btn->SetStyleForState(STYLE_BORDER_RADIUS, BUTTON_STYLE_BORDER_RADIUS_VALUE, UIButton::RELEASED); + btn->SetStyleForState(STYLE_BORDER_RADIUS, BUTTON_STYLE_BORDER_RADIUS_VALUE, UIButton::PRESSED); + btn->SetStyleForState(STYLE_BORDER_RADIUS, BUTTON_STYLE_BORDER_RADIUS_VALUE, UIButton::INACTIVE); + btn->SetStyleForState(STYLE_BACKGROUND_COLOR, BUTTON_STYLE_BACKGROUND_COLOR_VALUE, UIButton::RELEASED); + btn->SetStyleForState(STYLE_BACKGROUND_COLOR, BUTTON_STYLE_BACKGROUND_COLOR_VALUE, UIButton::PRESSED); + btn->SetStyleForState(STYLE_BACKGROUND_COLOR, BUTTON_STYLE_BACKGROUND_COLOR_VALUE, UIButton::INACTIVE); +} + +void UITestTransform::UIKit_Transform_Test_Rotate_001() +{ + rotateBtn_ = new UILabelButton(); + SetUpButton(rotateBtn_, "旋转"); +} + +void UITestTransform::UIKit_Transform_Test_Scale_002() +{ + scaleBtn_ = new UILabelButton(); + SetUpButton(scaleBtn_, "缩放"); +} + +void UITestTransform::UIKit_Transform_Test_Translate_003() +{ + translateBtn_ = new UILabelButton(); + SetUpButton(translateBtn_, "平移"); +} + +bool UITestTransform::OnClick(UIView& view, const ClickEvent& event) +{ + Rect viewRect = imageView_->GetOrigRect(); + TransformMap transMap(viewRect); + Vector2 pivot_(58, 58); // 58:x value 58:y value + if (&view == rotateBtn_) { + transMap.Rotate(90, pivot_); // 90:degree + } else if (&view == scaleBtn_) { + transMap.Scale(Vector2(1.5, 1.5), pivot_); // 1.5:x scale 1.5:y scale + } else if (&view == translateBtn_) { + transMap.Translate(Vector2(80, -30)); // 80:x-axis translation distance -30:y-axis translation distance + } + imageView_->SetTransformMap(transMap); + + return true; +} +} // namespace OHOS \ No newline at end of file diff --git a/test/uitest/test_transform/ui_test_transform.h b/test/uitest/test_transform/ui_test_transform.h new file mode 100755 index 0000000..132d049 --- /dev/null +++ b/test/uitest/test_transform/ui_test_transform.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef UI_TEST_TRANSFORM_H +#define UI_TEST_TRANSFORM_H + +#include "components/ui_image_view.h" +#include "components/ui_label.h" +#include "components/ui_label_button.h" +#include "components/ui_scroll_view.h" +#include "layout/grid_layout.h" +#include "ui_test.h" + +namespace OHOS { +class UITestTransform : public UITest, public UIView::OnClickListener { +public: + UITestTransform() {} + ~UITestTransform() {} + void SetUp() override; + void TearDown() override; + UIView* GetTestView() override; + + void SetUpButton(UILabelButton* btn, const char* title); + + bool OnClick(UIView& view, const ClickEvent& event) override; + + void UIKit_Transform_Test_Rotate_001(); + void UIKit_Transform_Test_Scale_002(); + void UIKit_Transform_Test_Translate_003(); + +private: + UIScrollView* container_ = nullptr; + GridLayout* layout_ = nullptr; + UIImageView* imageView_ = nullptr; + UIViewGroup* uiViewGroupFrame_ = nullptr; + + UILabelButton* rotateBtn_ = nullptr; + UILabelButton* scaleBtn_ = nullptr; + UILabelButton* translateBtn_ = nullptr; +}; +} // namespace OHOS +#endif // UI_TEST_TRANSFORM_H diff --git a/test/uitest/test_ui_analog_clock/ui_test_analog_clock.cpp b/test/uitest/test_ui_analog_clock/ui_test_analog_clock.cpp new file mode 100755 index 0000000..0f52251 --- /dev/null +++ b/test/uitest/test_ui_analog_clock/ui_test_analog_clock.cpp @@ -0,0 +1,315 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "ui_test_analog_clock.h" +#include "common/screen.h" +#include "components/ui_analog_clock.h" +#include "components/ui_image_view.h" +#include "components/ui_label.h" +#include "test_resource_config.h" + +namespace OHOS { +namespace { +const uint8_t BUTTON_TEXT_SIZE = 16; +const uint8_t BUTTON_WIDTH = 120; +const uint8_t BUTTON_HEIGHT = 40; +} // namespace + +void UITestAnalogClock::SetUp() +{ + if (container_ == nullptr) { + container_ = new UIScrollView(); + container_->Resize(Screen::GetInstance().GetWidth(), Screen::GetInstance().GetHeight() - BACK_BUTTON_HEIGHT); + } +} + +void UITestAnalogClock::TearDown() +{ + if (animator_ != nullptr) { + AnimatorManager::GetInstance()->Remove(animator_); + delete animator_; + delete callback_; + animator_ = nullptr; + callback_ = nullptr; + } + + if (animator2_ != nullptr) { + AnimatorManager::GetInstance()->Remove(animator2_); + delete animator2_; + delete callback2_; + animator2_ = nullptr; + callback2_ = nullptr; + } + + DeleteChildren(container_); + container_ = nullptr; +} + +UIView* UITestAnalogClock::GetTestView() +{ + UIKit_TestLineHandAnalogClock_001(); + UIKit_TestImageHandAnalogClock_002(); + return container_; +} + +class TestBtnOnClickChangeModeListener : public UIView::OnClickListener { +public: + TestBtnOnClickChangeModeListener(UIView* uiView, UIAnalogClock* clock) : uiView_(uiView), clock_(clock) {} + ~TestBtnOnClickChangeModeListener() {} + bool OnClick(UIView& view, const ClickEvent& event) override + { + if (clock_->GetWorkMode() == UIAbstractClock::ALWAYS_ON) { + clock_->SetWorkMode(UIAbstractClock::NORMAL); + } else { + clock_->SetWorkMode(UIAbstractClock::ALWAYS_ON); + } + return true; + } + +private: + UIView* uiView_; + UIAnalogClock* clock_; +}; + +class TestBtnOnClickMovePositionListener : public UIView::OnClickListener { +public: + enum class MoveType { + MOVE_LEFT, + MOVE_RIGHT, + MOVE_TOP, + MOVE_BOTTOM, + }; + TestBtnOnClickMovePositionListener(UIView* uiView, UIAnalogClock* clock, MoveType type, uint16_t grid) + : uiView_(uiView), clock_(clock), type_(type), grid_(grid) + { + } + ~TestBtnOnClickMovePositionListener() {} + bool OnClick(UIView& view, const ClickEvent& event) override + { + int16_t xPos = clock_->GetX(); + int16_t yPos = clock_->GetY(); + clock_->Invalidate(); + if (type_ == MoveType::MOVE_LEFT) { + xPos -= grid_; + } else if (type_ == MoveType::MOVE_RIGHT) { + xPos += grid_; + } else if (type_ == MoveType::MOVE_TOP) { + yPos -= grid_; + } else if (type_ == MoveType::MOVE_BOTTOM) { + yPos += grid_; + } + clock_->SetPosition(xPos, yPos); + return true; + } + +private: + UIView* uiView_; + UIAnalogClock* clock_; + MoveType type_; + uint16_t grid_; +}; + +void UITestAnalogClock::UIKit_TestLineHandAnalogClock_001() +{ + if (container_ != nullptr) { + UIViewGroup* group1 = new UIViewGroup(); + group1->SetPosition(0, 0); + group1->SetWidth(Screen::GetInstance().GetWidth()); + group1->SetHeight(Screen::GetInstance().GetHeight() + 100); // 100: height bigger value + container_->Add(group1); + + UILabel* label = new UILabel(); + group1->Add(label); + // 30: height + label->SetPosition(TEXT_DISTANCE_TO_LEFT_SIDE, TEXT_DISTANCE_TO_TOP_SIDE, Screen::GetInstance().GetWidth(), 30); + label->SetText("直线指针效果"); + label->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); + + UIAnalogClock* clock1 = new UIAnalogClock(); + group1->Add(clock1); + clock1->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE2, VIEW_DISTANCE_TO_TOP_SIDE, + Screen::GetInstance().GetWidth() / 2, // 2: half of screen width + Screen::GetInstance().GetHeight()); + + UIImageView* curFace = new UIImageView(); + curFace->SetSrc(B024_002_IMAGE_PATH); + clock1->Add(curFace); + curFace->SetPosition(0, 0); + // 214: position x 3:position y 14:center x 223:center y 1: width 223:height 255: opacity + clock1->SetHandLine(UIAnalogClock::HandType::SECOND_HAND, {214, 3}, {14, 223}, Color::White(), 1, 223, 255); + // 202: position x 25:position y 25:center x 201:center y 3: width 201:height 255: opacity + clock1->SetHandLine(UIAnalogClock::HandType::MINUTE_HAND, {202, 25}, {25, 201}, Color::Green(), 3, 201, 255); + // 202: position x 95:position y 25:center x 132:center y 5: width 132: height 255: opacity + clock1->SetHandLine(UIAnalogClock::HandType::HOUR_HAND, {202, 95}, {25, 132}, Color::Red(), 5, 132, 255); + clock1->SetInitTime24Hour(0, 0, 0); + clock1->SetWorkMode(UIAnalogClock::WorkMode::NORMAL); + clock1->SetTime24Hour(10, 3, 20); // 10: hour; 3: minute: 20: second + CreateButtons001(group1, curFace, clock1); + callback_ = new ClockAnimatorCallback(clock1); + animator_ = new Animator(callback_, clock1, 0, true); + AnimatorManager::GetInstance()->Add(animator_); + animator_->Start(); + } +} + +void UITestAnalogClock::CreateButtons001(UIViewGroup* group, UIImageView* curFace, UIAnalogClock* clock) +{ + if ((group == nullptr) || (curFace == nullptr) || (clock == nullptr)) { + return; + } + UILabelButton* button1 = SetUpButton("切换模式"); + group->Add(button1); + // 58: increase x-position; 48: y-position + button1->SetPosition(curFace->GetWidth() + 58, 48, BUTTON_WIDTH, BUTTON_HEIGHT); + UIView::OnClickListener* changeModeListener = + new TestBtnOnClickChangeModeListener(static_cast(button1), clock); + button1->SetOnClickListener(changeModeListener); + + UILabelButton* button2 = SetUpButton("左移"); + group->Add(button2); + // 58: increase x-position; 58: increase y-position + button2->SetPosition(curFace->GetWidth() + 58, BUTTON_HEIGHT + 58, BUTTON_WIDTH, BUTTON_HEIGHT); + UIView::OnClickListener* clickMoveLeftListener = new TestBtnOnClickMovePositionListener( + static_cast(button2), clock, TestBtnOnClickMovePositionListener::MoveType::MOVE_LEFT, 10); // 10: grid + button2->SetOnClickListener(clickMoveLeftListener); + + UILabelButton* button3 = SetUpButton("右移"); + group->Add(button3); + // 58: increase x-position; 148: y-position + button3->SetPosition(curFace->GetWidth() + 58, 148, BUTTON_WIDTH, BUTTON_HEIGHT); + UIView::OnClickListener* clickMoveRightListener = new TestBtnOnClickMovePositionListener( + static_cast(button3), clock, TestBtnOnClickMovePositionListener::MoveType::MOVE_RIGHT, + 10); // 10: grid + button3->SetOnClickListener(clickMoveRightListener); + + UILabelButton* button4 = SetUpButton("上移"); + group->Add(button4); + // 58: increase x-position; 198: y-position + button4->SetPosition(curFace->GetWidth() + 58, 198, BUTTON_WIDTH, BUTTON_HEIGHT); + UIView::OnClickListener* clickMoveTopListener = new TestBtnOnClickMovePositionListener( + static_cast(button4), clock, TestBtnOnClickMovePositionListener::MoveType::MOVE_TOP, + 10); // 10: move value + button4->SetOnClickListener(clickMoveTopListener); + + UILabelButton* button5 = SetUpButton("下移"); + group->Add(button5); + // 58: increase x-position; 248: y-position + button5->SetPosition(curFace->GetWidth() + 58, 248, BUTTON_WIDTH, BUTTON_HEIGHT); + UIView::OnClickListener* clickMoveBottomListener = new TestBtnOnClickMovePositionListener( + static_cast(button5), clock, TestBtnOnClickMovePositionListener::MoveType::MOVE_BOTTOM, + 10); // 10: move value + button5->SetOnClickListener(clickMoveBottomListener); +} + +void UITestAnalogClock::UIKit_TestImageHandAnalogClock_002() +{ + if (container_ != nullptr) { + UIViewGroup* group2 = new UIViewGroup(); + group2->SetPosition(0, Screen::GetInstance().GetHeight() + 50); // 50: increase y-coordinate + group2->SetWidth(Screen::GetInstance().GetWidth()); + group2->SetHeight(Screen::GetInstance().GetHeight() + 100); // 100: increase y-coordinate + container_->Add(group2); + + UILabel* label = new UILabel(); + group2->Add(label); + label->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE, 0, Screen::GetInstance().GetWidth(), 30); // 30: height + label->SetText("图片指针效果"); + label->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); + + UIImageView* image1 = new UIImageView(); + image1->SetSrc(B024_010_IMAGE_PATH); + UIImageView* image2 = new UIImageView(); + image2->SetSrc(B024_011_IMAGE_PATH); + UIImageView* image3 = new UIImageView(); + image3->SetSrc(B024_009_IMAGE_PATH); + + UIAnalogClock* clock2 = new UIAnalogClock(); + group2->Add(clock2); + clock2->SetDragParentInstead(true); + clock2->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE2, VIEW_DISTANCE_TO_TOP_SIDE, + Screen::GetInstance().GetWidth() / 2, // 2: half of screen width + Screen::GetInstance().GetHeight()); + + UIImageView* curFace = new UIImageView(); + curFace->SetSrc(B024_002_IMAGE_PATH); + clock2->Add(curFace); + curFace->SetPosition(0, 0); + // {214, 3}: position x, y {14, 223}: center x, y + clock2->SetHandImage(UIAnalogClock::HandType::SECOND_HAND, *image1, {214, 3}, {14, 223}); + // {202, 15}: position x, y {25, 211}: center x, y + clock2->SetHandImage(UIAnalogClock::HandType::MINUTE_HAND, *image2, {202, 15}, {25, 211}); + // {202, 15}: position x, y {25, 211}: center x, y + clock2->SetHandImage(UIAnalogClock::HandType::HOUR_HAND, *image3, {202, 15}, {25, 211}); + + clock2->SetInitTime24Hour(0, 0, 0); + clock2->SetWorkMode(UIAnalogClock::WorkMode::NORMAL); + clock2->SetTime24Hour(3, 3, 15); // 3: hour; 3: minute: 15: second + CreateButtons002(group2, curFace, clock2); + callback2_ = new ClockAnimatorCallback(clock2); + animator2_ = new Animator(callback2_, clock2, 0, true); + AnimatorManager::GetInstance()->Add(animator2_); + animator2_->Start(); + } +} + +void UITestAnalogClock::CreateButtons002(UIViewGroup* group, UIImageView* curFace, UIAnalogClock* clock) +{ + if ((group == nullptr) || (curFace == nullptr) || (clock == nullptr)) { + return; + } + UILabelButton* button1 = SetUpButton("切换模式"); + group->Add(button1); + // 58: increase x-coordinate; 48: y-coordinate + button1->SetPosition(curFace->GetWidth() + 58, 48, BUTTON_WIDTH, BUTTON_HEIGHT); + UIView::OnClickListener* changeModeListener = + new TestBtnOnClickChangeModeListener(static_cast(button1), clock); + button1->SetOnClickListener(changeModeListener); + + UILabelButton* button2 = SetUpButton("左移"); + group->Add(button2); + // 58: increase x-coordinate; 98: y-coordinate + button2->SetPosition(curFace->GetWidth() + 58, 98, BUTTON_WIDTH, BUTTON_HEIGHT); + UIView::OnClickListener* clickMoveLeftListener = new TestBtnOnClickMovePositionListener( + static_cast(button2), clock, TestBtnOnClickMovePositionListener::MoveType::MOVE_LEFT, 10); // 10: grid + button2->SetOnClickListener(clickMoveLeftListener); + + UILabelButton* button3 = SetUpButton("右移"); + group->Add(button3); + // 58: increase x-coordinate; 148: y-coordinate + button3->SetPosition(curFace->GetWidth() + 58, 148, BUTTON_WIDTH, BUTTON_HEIGHT); + UIView::OnClickListener* clickMoveRightListener = new TestBtnOnClickMovePositionListener( + static_cast(button3), clock, TestBtnOnClickMovePositionListener::MoveType::MOVE_RIGHT, + 10); // 10: move value + button3->SetOnClickListener(clickMoveRightListener); + + UILabelButton* button4 = SetUpButton("上移"); + group->Add(button4); + // 58: increase x-coordinate; 198: y-coordinate + button4->SetPosition(curFace->GetWidth() + 58, 198, BUTTON_WIDTH, BUTTON_HEIGHT); + UIView::OnClickListener* clickMoveTopListener = new TestBtnOnClickMovePositionListener( + static_cast(button4), clock, TestBtnOnClickMovePositionListener::MoveType::MOVE_TOP, + 10); // 10: move value + button4->SetOnClickListener(clickMoveTopListener); + UILabelButton* button5 = SetUpButton("下移"); + group->Add(button5); + // 58: increase x-coordinate; 248: y-coordinate + button5->SetPosition(curFace->GetWidth() + 58, 248, BUTTON_WIDTH, BUTTON_HEIGHT); + /* Move bottom */ + UIView::OnClickListener* clickMoveBottomListener = new TestBtnOnClickMovePositionListener( + static_cast(button5), clock, TestBtnOnClickMovePositionListener::MoveType::MOVE_BOTTOM, + 10); // 10: move value + button5->SetOnClickListener(clickMoveBottomListener); +} +} // namespace OHOS \ No newline at end of file diff --git a/test/uitest/test_ui_analog_clock/ui_test_analog_clock.h b/test/uitest/test_ui_analog_clock/ui_test_analog_clock.h new file mode 100755 index 0000000..7e0ef0f --- /dev/null +++ b/test/uitest/test_ui_analog_clock/ui_test_analog_clock.h @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef UI_TEST_ANALOG_CLOCK_H +#define UI_TEST_ANALOG_CLOCK_H + +#include "ui_test.h" + +#include "components/ui_analog_clock.h" +#include "components/ui_label_button.h" +#include "components/ui_scroll_view.h" + +namespace OHOS { +class ClockAnimatorCallback : public AnimatorCallback { +public: + explicit ClockAnimatorCallback(UIAnalogClock* clock) : clock_(clock) {} + ~ClockAnimatorCallback() {}; + virtual void Callback(UIView* view) + { + count_++; + if ((count_ == 30) && (clock_ != nullptr)) { // 30: run every tick (~30ms) + clock_->IncOneSecond(); + count_ = 0; + } + } +private: + UIAnalogClock* clock_; + int16_t count_ = 0; +}; + +class UITestAnalogClock : public UITest { +public: + UITestAnalogClock() {} + ~UITestAnalogClock() {} + void SetUp() override; + void TearDown() override; + UIView* GetTestView() override; + void CreateButtons001(UIViewGroup* group, UIImageView* curFace, UIAnalogClock* clock); + void CreateButtons002(UIViewGroup* group, UIImageView* curFace, UIAnalogClock* clock); + + void UIKit_TestLineHandAnalogClock_001(); + void UIKit_TestImageHandAnalogClock_002(); + +private: + UIScrollView* container_ = nullptr; + ClockAnimatorCallback* callback_ = nullptr; + Animator* animator_ = nullptr; + ClockAnimatorCallback* callback2_ = nullptr; + Animator* animator2_ = nullptr; + + UILabelButton* SetUpButton(const char* title) + { + UILabelButton* btn = new UILabelButton(); + btn->Resize(BUTTON_WIDHT2, BUTTON_HEIGHT2); + btn->SetText(title); + btn->SetFont(DEFAULT_VECTOR_FONT_FILENAME, BUTTON_LABEL_SIZE); + btn->SetStyleForState(STYLE_BORDER_RADIUS, BUTTON_STYLE_BORDER_RADIUS_VALUE, UIButton::RELEASED); + btn->SetStyleForState(STYLE_BORDER_RADIUS, BUTTON_STYLE_BORDER_RADIUS_VALUE, UIButton::PRESSED); + btn->SetStyleForState(STYLE_BORDER_RADIUS, BUTTON_STYLE_BORDER_RADIUS_VALUE, UIButton::INACTIVE); + btn->SetStyleForState(STYLE_BACKGROUND_COLOR, BUTTON_STYLE_BACKGROUND_COLOR_VALUE, UIButton::RELEASED); + btn->SetStyleForState(STYLE_BACKGROUND_COLOR, BUTTON_STYLE_BACKGROUND_COLOR_VALUE, UIButton::PRESSED); + btn->SetStyleForState(STYLE_BACKGROUND_COLOR, BUTTON_STYLE_BACKGROUND_COLOR_VALUE, UIButton::INACTIVE); + return btn; + } +}; +} +#endif // UI_TEST_ANALOG_CLOCK_H diff --git a/test/uitest/test_ui_dump_dom_tree/ui_test_dump_dom.cpp b/test/uitest/test_ui_dump_dom_tree/ui_test_dump_dom.cpp new file mode 100755 index 0000000..d1d29ff --- /dev/null +++ b/test/uitest/test_ui_dump_dom_tree/ui_test_dump_dom.cpp @@ -0,0 +1,435 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "graphic_config.h" + +#if ENABLE_DEBUG +#include "ui_test_dump_dom.h" + +#include "common/screen.h" +#include "components/ui_arc_label.h" +#include "components/ui_box_progress.h" +#include "components/ui_checkbox.h" +#include "components/ui_circle_progress.h" +#include "components/ui_image_view.h" +#include "components/ui_label.h" +#include "components/ui_label_button.h" +#include "components/ui_radio_button.h" +#include "components/ui_slider.h" +#include "components/ui_toggle_button.h" +#include "dfx/ui_dump_dom_tree.h" +#include "imgdecode/cache_manager.h" +#include "test_resource_config.h" +#include "graphic_log.h" + +namespace OHOS { +void UITestDumpDomTree::SetUp() +{ + if (container_ == nullptr) { + container_ = new UIScrollView(); + container_->Resize(Screen::GetInstance().GetWidth(), Screen::GetInstance().GetHeight() - BACK_BUTTON_HEIGHT); + container_->SetViewId("dump_scroll_view"); + } +} + +void UITestDumpDomTree::TearDown() +{ + positionY_ = 0; + DeleteChildren(container_); + container_ = nullptr; +} + +const UIView* UITestDumpDomTree::GetTestView() +{ + positionY_ = 0; + UIKit_TestDumpDom_001(); + UIKit_TestDumpDom_002(); + UIKit_TestDumpDom_003(); + UIKit_TestDumpDom_004(); + UIKit_TestDumpDom_005(); + UIKit_TestDumpDom_006(); + return container_; +} + +class TestBtnOnClickDumpDomListener : public UIView::OnClickListener { +public: + TestBtnOnClickDumpDomListener(UIView* uiView, const char* id) : uiView_(uiView), id_(id) {} + ~TestBtnOnClickDumpDomListener() {} + bool OnClick(UIView& view, const ClickEvent& event) override + { + char* tmpPtr = UIDumpDomTree::GetInstance()->DumpDomNode(id_); + if (tmpPtr != nullptr) { + cJSON_free(tmpPtr); + } + uiView_->Invalidate(); + return true; + } + +private: + UIView* uiView_; + const char* id_; +}; + +class TestBtnOnClickDumpDomTreeListener : public UIView::OnClickListener { +public: + TestBtnOnClickDumpDomTreeListener(UIView* uiView, const char* id) : uiView_(uiView), id_(id) {} + ~TestBtnOnClickDumpDomTreeListener() {} + bool OnClick(UIView& view, const ClickEvent& event) override + { + if (UIDumpDomTree::GetInstance()->DumpDomTree(id_)) { + if (id_ == nullptr) { + GRAPHIC_LOGI("dump tree from rootView success\n"); + } else { + GRAPHIC_LOGI("dump tree from id success\n"); + } + } else { + GRAPHIC_LOGI("dump tree failed\n"); + } + uiView_->Invalidate(); + return true; + } + +private: + UIView* uiView_; + const char* id_; +}; + +void UITestDumpDomTree::UIKit_TestDumpDom_001() +{ + if (container_ != nullptr) { + UILabel* label = GetTitleLabel("dump checkbox"); + container_->Add(label); + label->SetPosition(TEXT_DISTANCE_TO_LEFT_SIDE, TEXT_DISTANCE_TO_TOP_SIDE); + positionY_ += label->GetHeight(); + + GridLayout* layout = new GridLayout(); + layout->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE, VIEW_DISTANCE_TO_TOP_SIDE, + // 2: half of screen width; 88: decrease screen width; 180: height + Screen::GetInstance().GetWidth() / 2 - 88, 180); + layout->SetViewId("dump_group"); + container_->Add(layout); + positionY_ += layout->GetHeight(); + layout->SetRows(3); // 3: row + layout->SetCols(3); // 3: col + CreateButtons(layout); + layout->LayoutChildren(); + } +} + +void UITestDumpDomTree::CreateButtons(GridLayout* layout) +{ + if (layout == nullptr) { + return; + } + UICheckBox* checkBox = new UICheckBox(); + layout->Add(checkBox); + checkBox->SetState(UICheckBox::SELECTED); + checkBox->SetViewId("dump_checkbox"); + + UIRadioButton* radioButton = new UIRadioButton("aaa"); + layout->Add(radioButton); + radioButton->SetState(UICheckBox::UNSELECTED); + radioButton->SetViewId("dump_radiobutton"); + + UIToggleButton* toggleButton = new UIToggleButton(); + layout->Add(toggleButton); + toggleButton->SetStyle(STYLE_BACKGROUND_OPA, 0); + toggleButton->SetViewId("dump_togglebutton"); + + UILabelButton* dumpButton1 = GetLabelButton("dump"); + layout->Add(dumpButton1); + /* dump node here */ + UIView::OnClickListener* clickDumpDomListener1 = + new TestBtnOnClickDumpDomListener(static_cast(dumpButton1), "dump_checkbox"); + dumpButton1->SetOnClickListener(clickDumpDomListener1); + + UILabelButton* dumpButton2 = GetLabelButton("dump"); + layout->Add(dumpButton2); + /* dump node here */ + UIView::OnClickListener* clickDumpDomListener2 = + new TestBtnOnClickDumpDomListener(static_cast(dumpButton2), "dump_radiobutton"); + dumpButton2->SetOnClickListener(clickDumpDomListener2); + + UILabelButton* dumpButton3 = GetLabelButton("dump"); + layout->Add(dumpButton3); + /* dump node here */ + UIView::OnClickListener* clickDumpDomListener3 = + new TestBtnOnClickDumpDomListener(static_cast(dumpButton3), "dump_togglebutton"); + dumpButton3->SetOnClickListener(clickDumpDomListener3); + + UILabelButton* dumpButton4 = GetLabelButton("dump_all "); + layout->Add(dumpButton4); + UIView::OnClickListener* clickDumpDomTreeListener1 = + new TestBtnOnClickDumpDomTreeListener(static_cast(dumpButton4), nullptr); + dumpButton4->SetOnClickListener(clickDumpDomTreeListener1); + + UILabelButton* dumpButton5 = GetLabelButton("dump_group"); + layout->Add(dumpButton5); + UIView::OnClickListener* clickDumpDomTreeListener2 = + new TestBtnOnClickDumpDomTreeListener(static_cast(dumpButton5), "dump_group"); + dumpButton5->SetOnClickListener(clickDumpDomTreeListener2); +} + +void UITestDumpDomTree::UIKit_TestDumpDom_002() +{ + if (container_ != nullptr) { + UIViewGroup* group2 = new UIViewGroup(); + group2->SetPosition(Screen::GetInstance().GetWidth() / 2, 0); // 2: half of screen width + group2->SetWidth(Screen::GetInstance().GetWidth() / 2); // 2: half of screen width + group2->SetHeight(200); // 200: height + group2->SetViewId("dump_group2"); + container_->Add(group2); + positionY_ += group2->GetHeight(); + + UILabel* label = GetTitleLabel("dump image"); + group2->Add(label); + label->SetPosition(TEXT_DISTANCE_TO_LEFT_SIDE, TEXT_DISTANCE_TO_TOP_SIDE); + + UIImageView* imageView = new UIImageView(); + imageView->SetPosition(VIEW_DISTANCE_TO_TOP_SIDE, TEXT_DISTANCE_TO_LEFT_SIDE); + imageView->SetWidth(50); // 50: width + imageView->SetHeight(50); // 50: height + imageView->SetSrc(BLUE_RGB888_IMAGE_PATH); + imageView->SetViewId("dump_image"); + group2->Add(imageView); + + UILabelButton* dumpButton1 = GetLabelButton("dump"); + dumpButton1->SetPosition(160, 73); // 160: x-coordinate, 73: y-coordinate + group2->Add(dumpButton1); + dumpButton1->SetText("dump"); + /* dump node here */ + UIView::OnClickListener* clickDumpDomListener1 = + new TestBtnOnClickDumpDomListener(static_cast(dumpButton1), "dump_image"); + dumpButton1->SetOnClickListener(clickDumpDomListener1); + } +} + +void UITestDumpDomTree::UIKit_TestDumpDom_003() +{ + if (container_ != nullptr) { + UIViewGroup* group5 = new UIViewGroup(); + group5->SetPosition(0, 260); // 260: y-coordinate + group5->SetWidth(Screen::GetInstance().GetWidth() / 2); // 2: half of screen width + group5->SetHeight(200); // 200: height + group5->SetViewId("dump_group5"); + container_->Add(group5); + positionY_ += group5->GetHeight(); + + UILabel* label = GetTitleLabel("dump slider progress"); + label->SetPosition(TEXT_DISTANCE_TO_LEFT_SIDE, TEXT_DISTANCE_TO_TOP_SIDE); + group5->Add(label); + + UISlider* slider = new UISlider(); + // 50: new width, 100: new height + slider->SetPosition(TEXT_DISTANCE_TO_LEFT_SIDE, VIEW_DISTANCE_TO_TOP_SIDE, 50, 100); + slider->SetValidHeight(250); // 250: valid height + slider->SetDirection(UISlider::Direction::DIR_BOTTOM_TO_TOP); + slider->SetKnobWidth(50); // 50: knob width + slider->SetRange(100, 0); // 100: max + slider->SetValue(50); // 50: value of progress bar + slider->SetStep(0); + slider->SetBackgroundStyle(STYLE_BACKGROUND_COLOR, Color::GetColorFromRGB(0, 182, 191).full); // 182, 191: color + slider->SetForegroundStyle(STYLE_BACKGROUND_COLOR, Color::GetColorFromRGB(255, 152, 0).full); // 255, 152: color + slider->SetKnobStyle(StyleDefault::GetSliderKnobStyle()); + slider->SetImage(static_cast(nullptr), static_cast(nullptr), + static_cast(nullptr)); + slider->EnableBackground(true); + slider->SetViewId("dump_slider"); + group5->Add(slider); + + UILabelButton* dumpButton = GetLabelButton("dump"); + dumpButton->SetPosition(120, 73); // 120: x-coordinate, 73: y-coordinate + /* dump node here */ + UIView::OnClickListener* clickDumpDomListener = + new TestBtnOnClickDumpDomListener(static_cast(dumpButton), "dump_slider"); + dumpButton->SetOnClickListener(clickDumpDomListener); + group5->Add(dumpButton); + } +} + +void UITestDumpDomTree::UIKit_TestDumpDom_004() +{ + if (container_ != nullptr) { + UIViewGroup* group4 = new UIViewGroup(); + group4->SetPosition(Screen::GetInstance().GetWidth() / 2, 260); // 2: half of screen width; 260: y-coordinate + group4->SetWidth(Screen::GetInstance().GetWidth() / 2); // 2: half of screen width + group4->SetHeight(100); // 100: height + group4->SetViewId("dump_group4"); + container_->Add(group4); + positionY_ += group4->GetHeight(); + + UILabel* label = GetTitleLabel("dump box progress"); + label->SetPosition(TEXT_DISTANCE_TO_LEFT_SIDE, TEXT_DISTANCE_TO_TOP_SIDE); + group4->Add(label); + + UIBoxProgress* boxProgress = new UIBoxProgress(); + // 48: x-coordinate, 68: y-coordinate, 90: new width, 10: new height + boxProgress->SetPosition(48, 68, 90, 10); + boxProgress->SetDirection(UIBoxProgress::Direction::DIR_LEFT_TO_RIGHT); + boxProgress->SetValidHeight(10); // 10: valid height + boxProgress->SetValidWidth(100); // 100: valid width + boxProgress->SetRange(100, 0); // 100: max + boxProgress->SetValue(20); // 20 : value of progress bar + boxProgress->SetStep(0); + // 182, 191: color + boxProgress->SetBackgroundStyle(STYLE_BACKGROUND_COLOR, Color::GetColorFromRGB(0, 182, 191).full); + // 255, 152: color + boxProgress->SetForegroundStyle(STYLE_BACKGROUND_COLOR, Color::GetColorFromRGB(255, 152, 0).full); + boxProgress->SetImage(static_cast(nullptr)); + boxProgress->EnableBackground(true); + boxProgress->SetViewId("dump_boxprogress"); + group4->Add(boxProgress); + UILabelButton* dumpButton = GetLabelButton("dump"); + dumpButton->SetPosition(160, 48); // 160: x-coordinate, 48: y-coordinate + /* dump node here */ + UIView::OnClickListener* clickDumpDomListener = + new TestBtnOnClickDumpDomListener(static_cast(dumpButton), "dump_boxprogress"); + dumpButton->SetOnClickListener(clickDumpDomListener); + group4->Add(dumpButton); + } +} + +void UITestDumpDomTree::UIKit_TestDumpDom_005() +{ + if (container_ != nullptr) { + UIViewGroup* group3 = new UIViewGroup(); + group3->SetPosition(0, 450); // 450: y-coordinate + group3->SetWidth(Screen::GetInstance().GetWidth() / 2 - VIEW_DISTANCE_TO_LEFT_SIDE); // 2: half of screen width + group3->SetHeight(500); // 500: height + group3->SetViewId("dump_group3"); + container_->Add(group3); + + UILabel* label = GetTitleLabel("dump label"); + label->SetPosition(TEXT_DISTANCE_TO_LEFT_SIDE, TEXT_DISTANCE_TO_TOP_SIDE); + group3->Add(label); + + UILabel* label2 = GetTitleLabel("UILabel"); + label2->SetFont(DEFAULT_VECTOR_FONT_FILENAME, BUTTON_LABEL_SIZE); + label2->SetPosition(48, 58, 90, 29); // 48: x position, 58: y position, 90: width, 29: height + label2->SetViewId("dump_label"); + group3->Add(label2); + + UILabelButton* labelButton = GetLabelButton("LabelButton"); + labelButton->SetPosition(48, 108); // 48: x position, 108: y position + labelButton->SetViewId("dump_label_button"); + group3->Add(labelButton); + + UIArcLabel* label3 = new UIArcLabel(); + label3->SetArcTextCenter(70, 330); // 70: x position, 330: y position + label3->SetArcTextRadius(150); // 150: radius + label3->SetArcTextAngle(0, 270); // 0: start angle, 270: end angle + label3->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); + label3->SetText("012345678ABCDEF"); + label3->SetStyle(STYLE_LETTER_SPACE, 30); // 30: letter space + label3->SetViewId("dump_arc_label"); + group3->Add(label3); + + UILabelButton* dumpButton1 = GetLabelButton("dump"); + dumpButton1->SetPosition(230, 48); // 230: x-coordinate, 48: y-coordinate + /* dump node here */ + UIView::OnClickListener* clickDumpDomListener1 = + new TestBtnOnClickDumpDomListener(static_cast(dumpButton1), "dump_label"); + dumpButton1->SetOnClickListener(clickDumpDomListener1); + group3->Add(dumpButton1); + + UILabelButton* dumpButton2 = GetLabelButton("dump"); + dumpButton2->SetPosition(230, 108); // 230: x-coordinate, 108: y-coordinate + /* dump node here */ + UIView::OnClickListener* clickDumpDomListener2 = + new TestBtnOnClickDumpDomListener(static_cast(dumpButton2), "dump_label_button"); + dumpButton2->SetOnClickListener(clickDumpDomListener2); + group3->Add(dumpButton2); + + UILabelButton* dumpButton3 = GetLabelButton("dump"); + dumpButton3->SetPosition(230, 310); // 230: x position, 310: y position + /* dump node here */ + UIView::OnClickListener* clickDumpDomListener3 = + new TestBtnOnClickDumpDomListener(static_cast(dumpButton3), "dump_arc_label"); + dumpButton3->SetOnClickListener(clickDumpDomListener3); + group3->Add(dumpButton3); + } +} + +void UITestDumpDomTree::UIKit_TestDumpDom_006() +{ + if (container_ != nullptr) { + UIViewGroup* group6 = new UIViewGroup(); + // 2: half of screen width; 450: screen height + group6->SetPosition(Screen::GetInstance().GetWidth() / 2, 450); + group6->SetWidth(Screen::GetInstance().GetWidth() / 2); // 2: half of screen width + group6->SetHeight(250); // 250: height + group6->SetViewId("dump_group6"); + container_->Add(group6); + positionY_ += group6->GetHeight(); + + UILabel* label = GetTitleLabel("dump circle progress"); + label->SetPosition(TEXT_DISTANCE_TO_LEFT_SIDE, TEXT_DISTANCE_TO_TOP_SIDE); + group6->Add(label); + + UICircleProgress* circleProgress = new UICircleProgress(); + // 40: y-coordinate, 48: y-coordinate, 150: new width, 150: new height + circleProgress->SetPosition(40, 48, 150, 150); + circleProgress->SetCenterPosition(50, 50); // 50: x-coordinate, 50: y-coordinate + circleProgress->SetRadius(50); // 50: radius + circleProgress->SetValue(20); // 20: value of progress bar + circleProgress->SetStyle(STYLE_PADDING_LEFT, 10); // 10: padding left + circleProgress->SetStyle(STYLE_PADDING_TOP, 5); // 5: padding top + circleProgress->SetRange(100, 0); // 100: max + circleProgress->SetValue(50); // 50: value of progress bar + circleProgress->SetStartAngle(0); + circleProgress->SetEndAngle(360); // 360: end angle + circleProgress->SetStep(0); + circleProgress->SetBackgroundStyle(StyleDefault::GetProgressBackgroundStyle()); + circleProgress->SetForegroundStyle(StyleDefault::GetProgressForegroundStyle()); + circleProgress->SetLineColor(Color::White()); + circleProgress->EnableBackground(true); + circleProgress->SetViewId("dump_circle_progress"); + group6->Add(circleProgress); + + UILabelButton* dumpButton = GetLabelButton("dump"); + dumpButton->SetPosition(170, 73); // 170: x-coordinate, 73: y-coordinate + /* dump node here */ + UIView::OnClickListener* clickDumpDomListener = + new TestBtnOnClickDumpDomListener(static_cast(dumpButton), "dump_circle_progress"); + dumpButton->SetOnClickListener(clickDumpDomListener); + group6->Add(dumpButton); + } +} + +UILabelButton* UITestDumpDomTree::GetLabelButton(const char* buttonname) +{ + const int16_t labelButtonWidth = 120; + const int16_t labelButtonHeight = 40; + if (buttonname == nullptr) { + return nullptr; + } + UILabelButton* labelButton = new UILabelButton(); + if (labelButton == nullptr) { + return nullptr; + } + labelButton->SetPosition(0, 0); + labelButton->Resize(labelButtonWidth, labelButtonHeight); + labelButton->SetText(buttonname); + labelButton->SetFont(DEFAULT_VECTOR_FONT_FILENAME, BUTTON_LABEL_SIZE); + labelButton->SetStyleForState(STYLE_BORDER_RADIUS, BUTTON_STYLE_BORDER_RADIUS_VALUE, UIButton::RELEASED); + labelButton->SetStyleForState(STYLE_BORDER_RADIUS, BUTTON_STYLE_BORDER_RADIUS_VALUE, UIButton::PRESSED); + labelButton->SetStyleForState(STYLE_BORDER_RADIUS, BUTTON_STYLE_BORDER_RADIUS_VALUE, UIButton::INACTIVE); + labelButton->SetStyleForState(STYLE_BACKGROUND_COLOR, BUTTON_STYLE_BACKGROUND_COLOR_VALUE, UIButton::RELEASED); + labelButton->SetStyleForState(STYLE_BACKGROUND_COLOR, BUTTON_STYLE_BACKGROUND_COLOR_VALUE, UIButton::PRESSED); + labelButton->SetStyleForState(STYLE_BACKGROUND_COLOR, BUTTON_STYLE_BACKGROUND_COLOR_VALUE, UIButton::INACTIVE); + return labelButton; +} +} // namespace OHOS +#endif // ENABLE_DEBUG diff --git a/test/uitest/test_ui_dump_dom_tree/ui_test_dump_dom.h b/test/uitest/test_ui_dump_dom_tree/ui_test_dump_dom.h new file mode 100755 index 0000000..e7dab22 --- /dev/null +++ b/test/uitest/test_ui_dump_dom_tree/ui_test_dump_dom.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef GRAPHIC_LITE_UI_TEST_DUMP_DOM_H +#define GRAPHIC_LITE_UI_TEST_DUMP_DOM_H + +#include "graphic_config.h" + +#if ENABLE_DEBUG +#include "components/ui_label_button.h" +#include "components/ui_scroll_view.h" +#include "layout/grid_layout.h" +#include "ui_test.h" + +namespace OHOS { +class UITestDumpDomTree : public UITest { +public: + UITestDumpDomTree() {} + ~UITestDumpDomTree() {} + void SetUp() override; + void TearDown() override; + const UIView* GetTestView() override; + void CreateButtons(GridLayout* layout); + + void UIKit_TestDumpDom_001(); + void UIKit_TestDumpDom_002(); + void UIKit_TestDumpDom_003(); + void UIKit_TestDumpDom_004(); + void UIKit_TestDumpDom_005(); + void UIKit_TestDumpDom_006(); + UILabelButton* GetLabelButton(const char* buttonname); + +private: + UIScrollView* container_ = nullptr; +}; +} +#endif // ENABLE_DEBUG +#endif // GRAPHIC_LITE_UI_TEST_DUMP_DOM_H + diff --git a/test/uitest/test_ui_list/ui_test_ui_list.cpp b/test/uitest/test_ui_list/ui_test_ui_list.cpp new file mode 100755 index 0000000..1a53ca4 --- /dev/null +++ b/test/uitest/test_ui_list/ui_test_ui_list.cpp @@ -0,0 +1,367 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "ui_test_ui_list.h" +#include "common/screen.h" +#include "components/ui_label.h" +#include "components/ui_label_button.h" +#include "font/ui_font.h" + +namespace OHOS { +namespace { + static int16_t g_buttonH = 80; + static int16_t g_buttonW = 200; + static int16_t g_blank = 20; + static int16_t g_listW = 200; + static int16_t g_listH = 400; + static int16_t g_selectPos = 150; + static int16_t g_blankSize = 250; +} + +void UITestUIList::SetUp() +{ + if (container_ == nullptr) { + container_ = new UIScrollView(); + container_->Resize(Screen::GetInstance().GetWidth(), Screen::GetInstance().GetHeight() - BACK_BUTTON_HEIGHT); + container_->SetThrowDrag(true); + } + if (adapterData1_ == nullptr) { + adapterData1_ = new List(); + adapterData1_->PushBack("abcd0"); + adapterData1_->PushBack("abcd1"); + adapterData1_->PushBack("abcd2"); + adapterData1_->PushBack("abcd3"); + } + if (adapterData2_ == nullptr) { + adapterData2_ = new List(); + adapterData2_->PushBack("000"); + adapterData2_->PushBack("111"); + adapterData2_->PushBack("222"); + adapterData2_->PushBack("333"); + adapterData2_->PushBack("444"); + adapterData2_->PushBack("555"); + adapterData2_->PushBack("666"); + adapterData2_->PushBack("777"); + adapterData2_->PushBack("888"); + adapterData2_->PushBack("999"); + } +} + +void UITestUIList::TearDown() +{ + DeleteChildren(container_); + container_ = nullptr; + if (adapterData1_ != nullptr) { + adapterData1_->Clear(); + delete adapterData1_; + adapterData1_ = nullptr; + } + if (adapterData2_ != nullptr) { + adapterData2_->Clear(); + delete adapterData2_; + adapterData2_ = nullptr; + } + if (adapter1_ != nullptr) { + delete adapter1_; + adapter1_ = nullptr; + } + if (adapter2_ != nullptr) { + delete adapter2_; + adapter2_ = nullptr; + } + if (adapter3_ != nullptr) { + delete adapter3_; + adapter3_ = nullptr; + } + if (adapter4_ != nullptr) { + delete adapter4_; + adapter4_ = nullptr; + } + setBlankBtn_ = nullptr; + setBlankOffBtn_ = nullptr; + setThrowDragBtn_ = nullptr; + setThrowDragOffBtn_ = nullptr; + scrollStateLabel_ = nullptr; + scrollSelectLabel_ = nullptr; + setRefreshBtn_ = nullptr; + setLoopBtn_ = nullptr; + setLoopOffBtn_ = nullptr; + setSelectBtn_ = nullptr; + setSelectOffBtn_ = nullptr; + setAutoAlignBtn_ = nullptr; + setAutoAlignOffBtn_ = nullptr; + lastX_ = 0; + lastY_ = 0; +} + +const UIView* UITestUIList::GetTestView() +{ + UIKit_List_Init_Test_Full_Screen_001(); + UIKit_List_Init_Test_halh_Screen_001(); + UIKit_List_Scroll_Test_Blank_Set_001(); + return container_; +} + +void UITestUIList::UIKit_List_Init_Test_Full_Screen_001() +{ + if (container_ == nullptr) { + return; + } + UILabel* label = GetTitleLabel("UILIst设置adapter数据填满list"); + container_->Add(label); + label->SetPosition(TEXT_DISTANCE_TO_LEFT_SIDE, TEXT_DISTANCE_TO_TOP_SIDE); + + if (adapter1_ == nullptr) { + adapter1_ = new TextAdapter(); + } + adapter1_->SetData(adapterData2_); + + UIList* list = new UIList(UIList::VERTICAL); + list->SetStyle(STYLE_BACKGROUND_COLOR, Color::Red().full); + list->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE, VIEW_DISTANCE_TO_TOP_SIDE, g_listW, + g_listH - 200); // 200: mean list reduce height + list->SetStartIndex(5); // 5: list start index + list->GetStartIndex(); + list->SetAdapter(adapter1_); + container_->Add(list); +} + +void UITestUIList::UIKit_List_Init_Test_halh_Screen_001() +{ + if (container_ == nullptr) { + return; + } + UILabel* label = GetTitleLabel("UILIst设置adapter数据不填满list"); + container_->Add(label); + // 2: half of screen width + label->SetPosition(Screen::GetInstance().GetWidth() / 2 + TEXT_DISTANCE_TO_LEFT_SIDE, TEXT_DISTANCE_TO_TOP_SIDE); + + if (adapter2_ == nullptr) { + adapter2_ = new TextAdapter(); + } + adapter2_->SetData(adapterData1_); + + UIList* list = new UIList(UIList::VERTICAL); + list->SetStyle(STYLE_BACKGROUND_COLOR, Color::Red().full); + // 2: half of screen width + list->SetPosition(Screen::GetInstance().GetWidth() / 2 + VIEW_DISTANCE_TO_LEFT_SIDE, VIEW_DISTANCE_TO_TOP_SIDE, + g_listW, g_listH - 150); // 150: decrease height + list->SetAdapter(adapter2_); + container_->Add(list); +} + +void UITestUIList::SetControlButton() +{ + if (setBlankBtn_ == nullptr) { + setBlankBtn_ = new UILabelButton(); + } + if (setBlankOffBtn_ == nullptr) { + setBlankOffBtn_ = new UILabelButton(); + } + if (setThrowDragBtn_ == nullptr) { + setThrowDragBtn_ = new UILabelButton(); + } + if (setThrowDragOffBtn_ == nullptr) { + setThrowDragOffBtn_ = new UILabelButton(); + } + if (setRefreshBtn_ == nullptr) { + setRefreshBtn_ = new UILabelButton(); + } + if (setLoopBtn_ == nullptr) { + setLoopBtn_ = new UILabelButton(); + } + if (setLoopOffBtn_ == nullptr) { + setLoopOffBtn_ = new UILabelButton(); + } + if (setSelectBtn_ == nullptr) { + setSelectBtn_ = new UILabelButton(); + } + if (setSelectOffBtn_ == nullptr) { + setSelectOffBtn_ = new UILabelButton(); + } + if (setAutoAlignBtn_ == nullptr) { + setAutoAlignBtn_ = new UILabelButton(); + } + if (setAutoAlignOffBtn_ == nullptr) { + setAutoAlignOffBtn_ = new UILabelButton(); + } + + positionX_ += 5; // 5: increase y-coordinate + SetUpButton(setBlankBtn_, "开启blank"); + SetUpButton(setBlankOffBtn_, "关闭blank"); + SetUpButton(setThrowDragBtn_, "开启throwDrag"); + SetUpButton(setThrowDragOffBtn_, "关闭throwDrag"); + SetUpButton(setRefreshBtn_, "刷新list"); + SetUpButton(setLoopBtn_, "开启loop模式"); + SetUpButton(setLoopOffBtn_, "关闭loop模式"); + positionX_ = setBlankBtn_->GetX() + setBlankBtn_->GetWidth() + g_blank - VIEW_DISTANCE_TO_LEFT_SIDE; + positionY_ = setBlankBtn_->GetY(); + SetUpButton(setSelectBtn_, "select 150"); + SetUpButton(setSelectOffBtn_, "关闭select"); + SetUpButton(setAutoAlignBtn_, "开启自动对齐 "); + SetUpButton(setAutoAlignOffBtn_, "关闭自动对齐 "); +} + +void UITestUIList::UIKit_List_Scroll_Test_Blank_Set_001() +{ + if (container_ == nullptr) { + return; + } + UILabel* label = GetTitleLabel("UILIst设置blank和throwDrag"); + container_->Add(label); + label->SetPosition(TEXT_DISTANCE_TO_LEFT_SIDE, g_listH - 132); // 132: decrease y-coordinate + + if (adapter4_ == nullptr) { + adapter4_ = new TextAdapter(); + } + adapter4_->SetLineBreakMode(UILabel::LINE_BREAK_CLIP); + adapter4_->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); + adapter4_->SetHeight(100); // 100: mean adapter height + adapter4_->SetWidth(100); // 100: mean adapter width + adapter4_->SetData(adapterData2_); + + UIList* list = new UIList(UIList::VERTICAL); + list->SetStyle(STYLE_BACKGROUND_COLOR, Color::Red().full); + list->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE, g_listH - 95, g_listW, g_listH); // 95: decrease y-coordinate + list->SetAdapter(adapter4_); + list->SetScrollStateListener(this); + currentList_ = list; + + if (scrollStateLabel_ == nullptr) { + scrollStateLabel_ = new UILabel(); + } + if (scrollSelectLabel_ == nullptr) { + scrollSelectLabel_ = new UILabel(); + } + + scrollStateLabel_->SetLineBreakMode(UILabel::LINE_BREAK_ADAPT); + scrollSelectLabel_->SetLineBreakMode(UILabel::LINE_BREAK_ADAPT); + scrollStateLabel_->SetText("STOP"); + scrollSelectLabel_->SetText("NULL"); + + scrollStateLabel_->SetPosition(list->GetWidth() + 53, list->GetY()); // 53: increase x-coordinate + // 53: increase x-coordinate + scrollSelectLabel_->SetPosition(list->GetWidth() + scrollStateLabel_->GetWidth() + g_blank + 53, list->GetY()); + if (list->GetSelectView() != nullptr) { + scrollSelectLabel_->SetText(static_cast(list->GetSelectView())->GetText()); + } + positionX_ = list->GetWidth(); + positionY_ = scrollStateLabel_->GetY() + scrollStateLabel_->GetHeight(); + SetControlButton(); + + container_->Add(list); + UIView* selectBtnPos = new UIView(); + selectBtnPos->SetStyle(STYLE_BACKGROUND_OPA, OPA_OPAQUE); + selectBtnPos->SetStyle(STYLE_BACKGROUND_COLOR, Color::White().full); + selectBtnPos->SetStyle(STYLE_BORDER_WIDTH, 0); + selectBtnPos->SetStyle(STYLE_BORDER_RADIUS, 0); + selectBtnPos->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE, list->GetY() + g_selectPos, 100, 1); // 100: mean view width + container_->Add(selectBtnPos); + container_->Add(scrollStateLabel_); + container_->Add(scrollSelectLabel_); + SetLastPos(list); +} + +bool UITestUIList::OnClick(UIView& view, const ClickEvent& event) +{ + if (currentList_ == nullptr) { + return true; + } + if (&view == setBlankBtn_) { + currentList_->SetScrollBlankSize(g_blankSize); + } else if (&view == setBlankOffBtn_) { + currentList_->SetScrollBlankSize(0); + } else if (&view == setThrowDragBtn_) { + currentList_->SetThrowDrag(true); + } else if (&view == setThrowDragOffBtn_) { + currentList_->SetThrowDrag(false); + } else if (&view == setRefreshBtn_) { + adapter4_->SetData(adapterData1_); + currentList_->RefreshList(); + } else if (&view == setLoopBtn_) { + currentList_->SetLoopState(true); + } else if (&view == setLoopOffBtn_) { + currentList_->SetLoopState(false); + } else if (&view == setSelectBtn_) { + currentList_->SetSelectPosition(g_selectPos); + } else if (&view == setSelectOffBtn_) { + currentList_->SetSelectPosition(0); + } else if (&view == setAutoAlignBtn_) { + currentList_->EnableAutoAlign(true); + } else if (&view == setAutoAlignOffBtn_) { + currentList_->EnableAutoAlign(false); + } + return true; +} + +void UITestUIList::OnScrollStart(int16_t index, UIView* view) +{ + if (GetScrollState() == SCROLL_STATE_STOP) { + scrollStateLabel_->SetText("STOP"); + } else { + scrollStateLabel_->SetText("MOVE"); + } + + scrollStateLabel_->Invalidate(); +} + +void UITestUIList::OnScrollEnd(int16_t index, UIView* view) +{ + if (GetScrollState() == SCROLL_STATE_STOP) { + scrollStateLabel_->SetText("STOP"); + } else { + scrollStateLabel_->SetText("MOVE"); + } + scrollStateLabel_->Invalidate(); +} +void UITestUIList::OnItemSelected(int16_t index, UIView* view) +{ + if (view != nullptr) { + scrollSelectLabel_->SetText(static_cast(view)->GetText()); + view->Invalidate(); + } else { + scrollSelectLabel_->SetText("NULL"); + } +} + +void UITestUIList::SetUpButton(UILabelButton* btn, const char* title) +{ + if (btn == nullptr) { + return; + } + container_->Add(btn); + btn->SetPosition(positionX_ + VIEW_DISTANCE_TO_LEFT_SIDE, positionY_, BUTTON_WIDHT3, BUTTON_HEIGHT3); + positionY_ += btn->GetHeight() + 10; // 10: button interval + btn->SetText(title); + btn->SetFont(DEFAULT_VECTOR_FONT_FILENAME, BUTTON_LABEL_SIZE); + btn->SetOnClickListener(this); + btn->SetStyleForState(STYLE_BORDER_RADIUS, BUTTON_STYLE_BORDER_RADIUS_VALUE, UIButton::RELEASED); + btn->SetStyleForState(STYLE_BORDER_RADIUS, BUTTON_STYLE_BORDER_RADIUS_VALUE, UIButton::PRESSED); + btn->SetStyleForState(STYLE_BORDER_RADIUS, BUTTON_STYLE_BORDER_RADIUS_VALUE, UIButton::INACTIVE); + btn->SetStyleForState(STYLE_BACKGROUND_COLOR, BUTTON_STYLE_BACKGROUND_COLOR_VALUE, UIButton::RELEASED); + btn->SetStyleForState(STYLE_BACKGROUND_COLOR, BUTTON_STYLE_BACKGROUND_COLOR_VALUE, UIButton::PRESSED); + btn->SetStyleForState(STYLE_BACKGROUND_COLOR, BUTTON_STYLE_BACKGROUND_COLOR_VALUE, UIButton::INACTIVE); + container_->Invalidate(); +} + +void UITestUIList::SetLastPos(UIView* view) +{ + if (view == nullptr) { + return; + } + lastX_ = view->GetX(); + lastY_ = view->GetY() + view->GetHeight(); +} +} // namespace OHOS \ No newline at end of file diff --git a/test/uitest/test_ui_list/ui_test_ui_list.h b/test/uitest/test_ui_list/ui_test_ui_list.h new file mode 100755 index 0000000..f969d2e --- /dev/null +++ b/test/uitest/test_ui_list/ui_test_ui_list.h @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef UI_TEST_UI_LIST_H +#define UI_TEST_UI_LIST_H + +#include "components/text_adapter.h" +#include "components/ui_label.h" +#include "components/ui_label_button.h" +#include "components/ui_list.h" +#include "components/ui_scroll_view.h" +#include "ui_test.h" + +namespace OHOS { +class UITestUIList : public UITest, UIView::OnClickListener, ListScrollListener { +public: + UITestUIList() {} + ~UITestUIList() {} + void SetUp() override; + void TearDown() override; + const UIView* GetTestView() override; + + bool OnClick(UIView& view, const ClickEvent& event) override; + void OnScrollStart(int16_t index, UIView* view) override; + void OnScrollEnd(int16_t index, UIView* view) override; + void OnItemSelected(int16_t index, UIView* view) override; + void UIKit_List_Init_Test_Full_Screen_001(); + void UIKit_List_Init_Test_halh_Screen_001(); + void UIKit_List_Scroll_Test_Blank_Set_001(); + +private: + void SetLastPos(UIView* view); + void SetUpButton(UILabelButton* btn, const char* title); + void SetControlButton(); + UILabelButton* setBlankBtn_ = nullptr; + UILabelButton* setBlankOffBtn_ = nullptr; + UILabelButton* setThrowDragBtn_ = nullptr; + UILabelButton* setThrowDragOffBtn_ = nullptr; + UILabelButton* setRefreshBtn_ = nullptr; + UILabelButton* setLoopBtn_ = nullptr; + UILabelButton* setLoopOffBtn_ = nullptr; + UILabelButton* setSelectBtn_ = nullptr; + UILabelButton* setSelectOffBtn_ = nullptr; + UILabelButton* setAutoAlignBtn_ = nullptr; + UILabelButton* setAutoAlignOffBtn_ = nullptr; + UILabel* scrollStateLabel_ = nullptr; + UILabel* scrollSelectLabel_ = nullptr; + UIScrollView* container_ = nullptr; + List* adapterData1_ = nullptr; + List* adapterData2_ = nullptr; + TextAdapter* adapter1_ = nullptr; + TextAdapter* adapter2_ = nullptr; + TextAdapter* adapter3_ = nullptr; + TextAdapter* adapter4_ = nullptr; + UIList* currentList_ = nullptr; + UIList* currentList2_ = nullptr; + UILabel* lastSelectLabel_ = nullptr; + int16_t lastX_ = 0; + int16_t lastY_ = 0; +}; +} // namespace OHOS +#endif // UI_TEST_UI_LIST_H diff --git a/test/uitest/test_ui_list_view/ui_test_list_layout.cpp b/test/uitest/test_ui_list_view/ui_test_list_layout.cpp new file mode 100755 index 0000000..f391a7a --- /dev/null +++ b/test/uitest/test_ui_list_view/ui_test_list_layout.cpp @@ -0,0 +1,242 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "ui_test_list_layout.h" +#include "common/screen.h" +#include "components/ui_label.h" +#include "components/ui_label_button.h" +#include "layout/list_layout.h" + +namespace OHOS { +namespace { + static int16_t g_buttonH = 80; + static int16_t g_buttonW = 200; + static int16_t g_blank = 20; + static int16_t g_gap = 8; +} + +void UITestListLayout::SetUp() +{ + if (container_ == nullptr) { + container_ = new UIScrollView(); + container_->Resize(Screen::GetInstance().GetWidth(), Screen::GetInstance().GetHeight() - BACK_BUTTON_HEIGHT); + container_->SetThrowDrag(true); + } +} + +void UITestListLayout::TearDown() +{ + DeleteChildren(container_); + container_ = nullptr; + positionX_ = 0; + positionY_ = 0; + listDirect_ = nullptr; +} + +const UIView* UITestListLayout::GetTestView() +{ + UIKit_List_Vertical_Add_Test_Auto_Size_001(); + UIKit_List_Vertical_Remove_Test_Auto_Size_001(); + UIKit_List_Vertical_Remove_Test_Auto_Size_002(); + UIKit_List_Hor_Add_Test_Auto_Size_001(); + UIKit_List_Hor_Remove_Test_Auto_Size_001(); + UIKit_List_Hor_Remove_Test_Auto_Size_002(); + return container_; +} + +void UITestListLayout::UIKit_List_Vertical_Add_Test_Auto_Size_001() +{ + if (container_ == nullptr) { + return; + } + UILabel* label = GetTitleLabel("UILIst高度自适应 Add Insert"); + container_->Add(label); + label->SetPosition(TEXT_DISTANCE_TO_LEFT_SIDE, positionY_ + g_blank); + + ListLayout* list = new ListLayout(); + list->SetDirection(ListLayout::VERTICAL); + list->SetStyle(STYLE_BACKGROUND_COLOR, Color::Red().full); + list->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE, label->GetY() + TITLE_LABEL_DEFAULT_HEIGHT + g_gap); + list->Resize(Screen::GetInstance().GetWidth() - 100, 0); // 100: list reduce width + container_->Add(list); + + UILabelButton* button1 = new UILabelButton(); + button1->SetPosition(0, 0, g_buttonW, g_buttonH); + button1->SetText("button1"); + list->Add(button1); + UILabelButton* button2 = new UILabelButton(); + button2->SetPosition(0, 0, g_buttonW, g_buttonH); + button2->SetText("button2"); + list->Insert(button1, button2); + + if (listDirect_ == nullptr) { + listDirect_ = new UILabel(); + } + listDirect_->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); + listDirect_->SetPosition(list->GetX(), list->GetY(), 100, 100); // 100: list dir width and height + if (list->GetDirection() == ListLayout::VERTICAL) { + listDirect_->SetText("VERTICAL"); + } else { + listDirect_->SetText("HROIZONTAL"); + } + + container_->Add(listDirect_); + + SetLastPos(list); +} + +void UITestListLayout::UIKit_List_Vertical_Remove_Test_Auto_Size_001() +{ + if (container_ == nullptr) { + return; + } + UILabel* label = GetTitleLabel("UILIst高度自适应 Remove"); + container_->Add(label); + label->SetPosition(TEXT_DISTANCE_TO_LEFT_SIDE, positionY_ + g_blank); + + ListLayout* list = new ListLayout(ListLayout::VERTICAL); + list->SetStyle(STYLE_BACKGROUND_COLOR, Color::Red().full); + + list->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE, label->GetY() + TITLE_LABEL_DEFAULT_HEIGHT + g_gap, + Screen::GetInstance().GetWidth() - 100, 0); // 100: list reduce width + container_->Add(list); + UILabelButton* button1 = new UILabelButton(); + button1->SetPosition(0, 0, g_buttonW, g_buttonH); + button1->SetText("button1"); + list->Add(button1); + UILabelButton* button2 = new UILabelButton(); + button2->SetPosition(0, 0, g_buttonW, g_buttonH); + button2->SetText("button2"); + list->Add(button2); + list->Remove(button1); + SetLastPos(list); +} + +void UITestListLayout::UIKit_List_Vertical_Remove_Test_Auto_Size_002() +{ + if (container_ == nullptr) { + return; + } + UILabel* label = GetTitleLabel("UILIst高度自适应 RemoveAll"); + container_->Add(label); + label->SetPosition(TEXT_DISTANCE_TO_LEFT_SIDE, positionY_ + g_blank); + + ListLayout* list = new ListLayout(ListLayout::VERTICAL); + list->SetStyle(STYLE_BACKGROUND_COLOR, Color::Red().full); + + list->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE, label->GetY() + TITLE_LABEL_DEFAULT_HEIGHT + g_gap, + Screen::GetInstance().GetWidth() - 100, 0); // 100: list reduce width + container_->Add(list); + UILabelButton* button1 = new UILabelButton(); + button1->SetPosition(0, 0, g_buttonW, g_buttonH); + button1->SetText("button1"); + list->Add(button1); + UILabelButton* button2 = new UILabelButton(); + button2->SetPosition(0, 0, g_buttonW, g_buttonH); + button2->SetText("button2"); + list->Add(button2); + list->RemoveAll(); + SetLastPos(list); +} + +void UITestListLayout::UIKit_List_Hor_Add_Test_Auto_Size_001() +{ + if (container_ == nullptr) { + return; + } + UILabel* label = GetTitleLabel("UILIst宽度自适应 Add Insert"); + container_->Add(label); + label->SetPosition(TEXT_DISTANCE_TO_LEFT_SIDE, positionY_ + g_blank); + + ListLayout* list = new ListLayout(ListLayout::HORIZONTAL); + list->SetStyle(STYLE_BACKGROUND_COLOR, Color::Red().full); + + list->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE, label->GetY() + TITLE_LABEL_DEFAULT_HEIGHT + g_gap, 0, + Screen::GetInstance().GetHeight()); + container_->Add(list); + UILabelButton* button1 = new UILabelButton(); + button1->SetPosition(0, 0, g_buttonW, g_buttonH); + button1->SetText("button1"); + list->Add(button1); + UILabelButton* button2 = new UILabelButton(); + button2->SetPosition(0, 0, g_buttonW, g_buttonH); + button2->SetText("button2"); + list->Insert(button1, button2); + SetLastPos(list); +} + +void UITestListLayout::UIKit_List_Hor_Remove_Test_Auto_Size_001() +{ + if (container_ == nullptr) { + return; + } + UILabel* label = GetTitleLabel("UILIst宽度自适应 Remove"); + container_->Add(label); + label->SetPosition(TEXT_DISTANCE_TO_LEFT_SIDE, positionY_ + g_blank); + + ListLayout* list = new ListLayout(ListLayout::HORIZONTAL); + list->SetStyle(STYLE_BACKGROUND_COLOR, Color::Red().full); + + list->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE, label->GetY() + TITLE_LABEL_DEFAULT_HEIGHT + g_gap, 0, + Screen::GetInstance().GetHeight()); + container_->Add(list); + UILabelButton* button1 = new UILabelButton(); + button1->SetPosition(0, 0, g_buttonW, g_buttonH); + button1->SetText("button1"); + list->Add(button1); + UILabelButton* button2 = new UILabelButton(); + button2->SetPosition(0, 0, g_buttonW, g_buttonH); + button2->SetText("button2"); + list->Add(button2); + list->Remove(button1); + SetLastPos(list); +} + +void UITestListLayout::UIKit_List_Hor_Remove_Test_Auto_Size_002() +{ + if (container_ == nullptr) { + return; + } + UILabel* label = GetTitleLabel("UILIst宽度自适应 RemoveAll"); + container_->Add(label); + label->SetPosition(TEXT_DISTANCE_TO_LEFT_SIDE, positionY_ + g_blank); + + ListLayout* list = new ListLayout(ListLayout::HORIZONTAL); + list->SetStyle(STYLE_BACKGROUND_COLOR, Color::Red().full); + + list->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE, label->GetY() + TITLE_LABEL_DEFAULT_HEIGHT + g_gap, 0, + Screen::GetInstance().GetHeight()); + container_->Add(list); + UILabelButton* button1 = new UILabelButton(); + button1->SetPosition(0, 0, g_buttonW, g_buttonH); + button1->SetText("button1"); + list->Add(button1); + UILabelButton* button2 = new UILabelButton(); + button2->SetPosition(0, 0, g_buttonW, g_buttonH); + button2->SetText("button2"); + list->Add(button2); + list->RemoveAll(); + SetLastPos(list); +} + +void UITestListLayout::SetLastPos(UIView* view) +{ + if (view == nullptr) { + return; + } + positionX_ = view->GetX(); + positionY_ = view->GetY() + view->GetHeight(); +} +} // namespace OHOS \ No newline at end of file diff --git a/test/uitest/test_ui_list_view/ui_test_list_layout.h b/test/uitest/test_ui_list_view/ui_test_list_layout.h new file mode 100755 index 0000000..3599d93 --- /dev/null +++ b/test/uitest/test_ui_list_view/ui_test_list_layout.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef UI_TEST_UI_LIST_VIEW_H +#define UI_TEST_UI_LIST_VIEW_H + +#include "components/ui_label.h" +#include "components/ui_scroll_view.h" +#include "ui_test.h" + +namespace OHOS { +class UITestListLayout : public UITest { +public: + UITestListLayout() {} + ~UITestListLayout() {} + void SetUp() override; + void TearDown() override; + const UIView* GetTestView() override; + + void UIKit_List_Vertical_Add_Test_Auto_Size_001(); + void UIKit_List_Vertical_Remove_Test_Auto_Size_001(); + void UIKit_List_Vertical_Remove_Test_Auto_Size_002(); + void UIKit_List_Hor_Add_Test_Auto_Size_001(); + void UIKit_List_Hor_Remove_Test_Auto_Size_001(); + void UIKit_List_Hor_Remove_Test_Auto_Size_002(); + +private: + void SetLastPos(UIView* view); + UIScrollView* container_ = nullptr; + int16_t lastX_ = 0; + int16_t lastY_ = 0; + UILabel* listDirect_ = nullptr; +}; +} // namespace OHOS +#endif // UI_TEST_INPUT_EVENT_H diff --git a/test/uitest/test_ui_scroll_view/ui_test_ui_scroll_view.cpp b/test/uitest/test_ui_scroll_view/ui_test_ui_scroll_view.cpp new file mode 100755 index 0000000..a54998a --- /dev/null +++ b/test/uitest/test_ui_scroll_view/ui_test_ui_scroll_view.cpp @@ -0,0 +1,318 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "ui_test_ui_scroll_view.h" +#include "common/screen.h" +#include "components/ui_label_button.h" + +namespace OHOS { +namespace { +static int16_t g_buttonH = 400; +static int16_t g_buttonW = 400; +static int16_t g_smallButtonH = 40; +static int16_t g_smallButtonW = 40; +static int16_t g_blank = 20; +static int16_t g_scrollH = 300; +static int16_t g_scrollW = 300; +static UILabel* g_scrollSateLabel = nullptr; +const int16_t DELTA_Y_COORDINATE = 19; +const int16_t DELTA_Y_COORDINATE_2 = 37; +} // namespace + +class TestOnScrollListener : public UIScrollView::OnScrollListener { + void OnScrollStart() override + { + g_scrollSateLabel->SetText("moving"); + g_scrollSateLabel->Invalidate(); + } + + void OnScrollEnd() override + { + g_scrollSateLabel->SetText("stop"); + g_scrollSateLabel->Invalidate(); + } +}; + +static TestOnScrollListener* g_listener = nullptr; + +void UITestUIScrollView::SetUp() +{ + if (container_ == nullptr) { + container_ = new UIScrollView(); + container_->Resize(Screen::GetInstance().GetWidth(), Screen::GetInstance().GetHeight() - BACK_BUTTON_HEIGHT); + container_->SetThrowDrag(true); + } + if (g_scrollSateLabel == nullptr) { + g_scrollSateLabel = GetTitleLabel("stop"); + g_scrollSateLabel->SetPosition(0, 0, 100, TITLE_LABEL_DEFAULT_HEIGHT); // 100: width + g_scrollSateLabel->SetLineBreakMode(UILabel::LINE_BREAK_ADAPT); + } + + if (g_listener == nullptr) { + g_listener = new TestOnScrollListener(); + } +} + +void UITestUIScrollView::TearDown() +{ + container_->Remove(g_scrollSateLabel); + DeleteChildren(container_); + container_ = nullptr; + if (g_scrollSateLabel != nullptr) { + delete g_scrollSateLabel; + g_scrollSateLabel = nullptr; + } + if (g_listener != nullptr) { + delete g_listener; + g_listener = nullptr; + } + lastX_ = 0; + lastY_ = 0; +} + +const UIView* UITestUIScrollView::GetTestView() +{ + UIKit_UIScrollView_Test_bar_001(); + UIKit_UIScrollView_Test_bar_002(); + UIKit_UIScrollView_Test_bar_003(); + UIKit_UIScrollView_Test_bar_004(); + UIKit_UIScrollView_Test_Scrollable_Set_001(); + UIKit_UIScrollView_Test_Scrollable_Set_002(); + UIKit_UIScrollView_Test_Scroll_Blank_Set_001(); + UIKit_UIScrollView_Test_Scroll_listener_001(); + return container_; +} + +void UITestUIScrollView::UIKit_UIScrollView_Test_bar_001() +{ + if (container_ == nullptr) { + return; + } + positionX_ = TEXT_DISTANCE_TO_LEFT_SIDE; + positionY_ = TEXT_DISTANCE_TO_TOP_SIDE; + UILabel* label = GetTitleLabel("UIScrollView设置游标不可见 "); + label->SetPosition(positionX_, positionY_); + container_->Add(label); + positionY_ += DELTA_Y_COORDINATE_2; + + UIScrollView* scroll = new UIScrollView(); + scroll->SetStyle(STYLE_BACKGROUND_COLOR, Color::Red().full); + scroll->SetPosition(positionX_, positionY_, g_scrollW, g_scrollH); + scroll->SetXScrollBarVisible(false); + scroll->SetYScrollBarVisible(false); + container_->Add(scroll); + UILabelButton* button1 = new UILabelButton(); + button1->SetPosition(0, 0, g_buttonW, g_buttonH); + button1->SetText("button1"); + scroll->Add(button1); + SetLastPos(scroll); + positionY_ += g_scrollH; +} + +void UITestUIScrollView::UIKit_UIScrollView_Test_bar_002() +{ + if (container_ == nullptr) { + return; + } + UILabel* label = GetTitleLabel("UIScrollView设置游标可见 "); + container_->Add(label); + positionY_ += DELTA_Y_COORDINATE; + label->SetPosition(positionX_, positionY_); + positionY_ += DELTA_Y_COORDINATE_2; + + UIScrollView* scroll = new UIScrollView(); + scroll->SetStyle(STYLE_BACKGROUND_COLOR, Color::Red().full); + scroll->SetPosition(positionX_, positionY_, g_scrollW, g_scrollH); + scroll->SetXScrollBarVisible(true); + scroll->SetYScrollBarVisible(true); + container_->Add(scroll); + UIButton* button1 = new UIButton(); + button1->SetPosition(0, 0, g_smallButtonW, g_smallButtonH); + scroll->Add(button1); + SetLastPos(scroll); + positionY_ += g_scrollH; +} + +void UITestUIScrollView::UIKit_UIScrollView_Test_bar_003() +{ + if (container_ == nullptr) { + return; + } + UILabel* label = GetTitleLabel("UIScrollView游标滑动状态 "); + container_->Add(label); + positionY_ += DELTA_Y_COORDINATE; + label->SetPosition(positionX_, positionY_); + positionY_ += DELTA_Y_COORDINATE_2; + + UIScrollView* scroll = new UIScrollView(); + scroll->SetStyle(STYLE_BACKGROUND_COLOR, Color::Red().full); + scroll->SetPosition(positionX_, positionY_, g_scrollW, g_scrollH); + scroll->SetXScrollBarVisible(true); + scroll->SetYScrollBarVisible(true); + container_->Add(scroll); + UILabelButton* button1 = new UILabelButton(); + button1->SetText("button1"); + button1->SetPosition(0, 0, g_buttonW, g_buttonH); + UILabelButton* button2 = new UILabelButton(); + button2->SetText("button2"); + button2->SetPosition(0, g_buttonH, g_buttonW, g_buttonH); + scroll->Add(button1); + scroll->Add(button2); + SetLastPos(scroll); + positionY_ += g_scrollH; +} + +void UITestUIScrollView::UIKit_UIScrollView_Test_bar_004() +{ + if (container_ == nullptr) { + return; + } + UILabel* label = GetTitleLabel("UIScrollView设置游标宽度为20"); + container_->Add(label); + positionY_ += DELTA_Y_COORDINATE; + label->SetPosition(positionX_, positionY_); + positionY_ += DELTA_Y_COORDINATE_2; + + UIScrollView* scroll = new UIScrollView(); + scroll->SetStyle(STYLE_BACKGROUND_COLOR, Color::Red().full); + scroll->SetPosition(positionX_, positionY_, g_scrollW, g_scrollH); + scroll->SetXScrollBarVisible(true); + scroll->SetYScrollBarVisible(true); + scroll->SetScrollbarWidth(20); // 20: means scroll bar width + container_->Add(scroll); + UIButton* button1 = new UIButton(); + button1->SetPosition(0, 0, g_smallButtonW, g_smallButtonH); + scroll->Add(button1); + SetLastPos(scroll); + positionY_ += g_scrollH; +} + +void UITestUIScrollView::UIKit_UIScrollView_Test_Scrollable_Set_001() +{ + if (container_ == nullptr) { + return; + } + positionX_ = Screen::GetInstance().GetWidth() / 2 + TEXT_DISTANCE_TO_LEFT_SIDE; // 2: half of screen width + positionY_ = TEXT_DISTANCE_TO_TOP_SIDE; + UILabel* label = GetTitleLabel("UIScrollView设置仅垂直方向可滑动 "); + container_->Add(label); + label->SetPosition(positionX_, positionY_); + positionY_ += DELTA_Y_COORDINATE_2; + + UIScrollView* scroll = new UIScrollView(); + scroll->SetStyle(STYLE_BACKGROUND_COLOR, Color::Red().full); + scroll->SetPosition(positionX_, positionY_, g_scrollW, g_scrollH); + scroll->SetScrollBlankSize(20); // 20: means scroll blank size + scroll->SetHorizontalScrollState(false); + scroll->SetVerticalScrollState(true); + scroll->SetXScrollBarVisible(true); + scroll->SetYScrollBarVisible(true); + container_->Add(scroll); + UILabelButton* button1 = new UILabelButton(); + button1->SetPosition(0, 0, g_buttonW, g_buttonH); + button1->SetText("button1"); + scroll->Add(button1); + SetLastPos(scroll); + positionY_ += g_scrollH; +} + +void UITestUIScrollView::UIKit_UIScrollView_Test_Scrollable_Set_002() +{ + if (container_ == nullptr) { + return; + } + UILabel* label = GetTitleLabel("UIScrollView设置仅垂直方向不可滑动 "); + container_->Add(label); + positionY_ += DELTA_Y_COORDINATE; + label->SetPosition(positionX_, positionY_); + positionY_ += DELTA_Y_COORDINATE_2; + + UIScrollView* scroll = new UIScrollView(); + scroll->SetStyle(STYLE_BACKGROUND_COLOR, Color::Red().full); + scroll->SetPosition(positionX_, positionY_, g_scrollW, g_scrollH); + scroll->SetHorizontalScrollState(true); + scroll->SetVerticalScrollState(false); + scroll->SetXScrollBarVisible(true); + scroll->SetYScrollBarVisible(true); + container_->Add(scroll); + UILabelButton* button1 = new UILabelButton(); + button1->SetPosition(0, 0, g_buttonW, g_buttonH); + button1->SetText("button1"); + scroll->Add(button1); + SetLastPos(scroll); + positionY_ += g_scrollH; +} + +void UITestUIScrollView::UIKit_UIScrollView_Test_Scroll_Blank_Set_001() +{ + if (container_ == nullptr) { + return; + } + UILabel* label = GetTitleLabel("UIScrollView设置高为50的可滑动空白区域 "); + container_->Add(label); + positionY_ += DELTA_Y_COORDINATE; + label->SetPosition(positionX_, positionY_); + positionY_ += DELTA_Y_COORDINATE_2; + + UIScrollView* scroll = new UIScrollView(); + scroll->SetStyle(STYLE_BACKGROUND_COLOR, Color::Red().full); + scroll->SetPosition(positionX_, positionY_, g_scrollW, g_scrollH); + scroll->SetScrollBlankSize(50); // (50): means scroll blank size + scroll->SetXScrollBarVisible(true); + scroll->SetYScrollBarVisible(true); + container_->Add(scroll); + UILabelButton* button1 = new UILabelButton(); + button1->SetPosition(0, 0, g_buttonW, g_buttonH); + button1->SetText("button1"); + scroll->Add(button1); + SetLastPos(scroll); + positionY_ += g_scrollH; +} + +void UITestUIScrollView::UIKit_UIScrollView_Test_Scroll_listener_001() +{ + if (container_ == nullptr) { + return; + } + UILabel* label = GetTitleLabel("UIScrollView设置滑动状态监听 "); + container_->Add(label); + positionY_ += DELTA_Y_COORDINATE; + label->SetPosition(positionX_, positionY_); + positionY_ += DELTA_Y_COORDINATE_2; + + UIScrollView* scroll = new UIScrollView(); + scroll->SetStyle(STYLE_BACKGROUND_COLOR, Color::Red().full); + scroll->SetPosition(positionX_, positionY_, g_scrollW, g_scrollH); + container_->Add(scroll); + UILabelButton* button1 = new UILabelButton(); + button1->SetPosition(0, 0, g_buttonW, g_buttonH); + button1->SetText("button1"); + scroll->Add(button1); + scroll->RegisterScrollListener(g_listener); + g_scrollSateLabel->SetPosition(positionX_ + scroll->GetWidth() + 10, scroll->GetY()); // 10: increase width + container_->Add(g_scrollSateLabel); + + SetLastPos(scroll); +} + +void UITestUIScrollView::SetLastPos(UIView* view) +{ + if (view == nullptr) { + return; + } + lastX_ = view->GetX(); + lastY_ = view->GetY() + view->GetHeight(); +} +} // namespace OHOS \ No newline at end of file diff --git a/test/uitest/test_ui_scroll_view/ui_test_ui_scroll_view.h b/test/uitest/test_ui_scroll_view/ui_test_ui_scroll_view.h new file mode 100755 index 0000000..693b189 --- /dev/null +++ b/test/uitest/test_ui_scroll_view/ui_test_ui_scroll_view.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef UI_TEST_UI_SCROLL_VIEW_H +#define UI_TEST_UI_SCROLL_VIEW_H + +#include "components/ui_label.h" +#include "components/ui_scroll_view.h" +#include "ui_test.h" + +namespace OHOS { +class UITestUIScrollView : public UITest { +public: + UITestUIScrollView() {} + ~UITestUIScrollView() {} + void SetUp() override; + void TearDown() override; + const UIView* GetTestView() override; + + void UIKit_UIScrollView_Test_bar_001(); + void UIKit_UIScrollView_Test_bar_002(); + void UIKit_UIScrollView_Test_bar_003(); + void UIKit_UIScrollView_Test_bar_004(); + void UIKit_UIScrollView_Test_Scrollable_Set_001(); + void UIKit_UIScrollView_Test_Scrollable_Set_002(); + void UIKit_UIScrollView_Test_Scroll_Blank_Set_001(); + void UIKit_UIScrollView_Test_Scroll_listener_001(); + +private: + void SetLastPos(UIView* view); + UIScrollView* container_ = nullptr; + int16_t lastX_ = 0; + int16_t lastY_ = 0; +}; +} // namespace OHOS +#endif // UI_TEST_UI_SCROLL_VIEW_H diff --git a/test/uitest/test_ui_swipe_view/ui_test_ui_swipe_view.cpp b/test/uitest/test_ui_swipe_view/ui_test_ui_swipe_view.cpp new file mode 100755 index 0000000..94c218e --- /dev/null +++ b/test/uitest/test_ui_swipe_view/ui_test_ui_swipe_view.cpp @@ -0,0 +1,366 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "ui_test_ui_swipe_view.h" + +#include + +#include "common/screen.h" +#include "components/ui_label.h" +#include "components/ui_swipe_view.h" + +namespace OHOS { +namespace { +static int16_t g_buttonH = 80; +static int16_t g_buttonW = 300; +static int16_t g_blank = 20; +static int16_t g_swipeH = 200; +static int16_t g_swipeW = 400; +static int16_t g_deltaCoordinateY = 19; +static int16_t g_deltaCoordinateY2 = 37; +} // namespace + +void UITestUISwipeView::SetUp() +{ + if (container_ == nullptr) { + container_ = new UIScrollView(); + container_->Resize(Screen::GetInstance().GetWidth(), Screen::GetInstance().GetHeight() - BACK_BUTTON_HEIGHT); + container_->SetThrowDrag(true); + container_->SetHorizontalScrollState(false); + } +} + +void UITestUISwipeView::TearDown() +{ + DeleteChildren(container_); + container_ = nullptr; + addBtnInHead_ = nullptr; + addBtnInTail_ = nullptr; + addBtnInMid_ = nullptr; + removeHeadBtn_ = nullptr; + removeMidBtn_ = nullptr; + removeAllBtn_ = nullptr; + lastX_ = 0; + lastY_ = 0; +} + +const UIView* UITestUISwipeView::GetTestView() +{ + UIKit_Swipe_View_Test_Horizontal_001(); + UIKit_Swipe_View_Test_Horizontal_002(); + UIKit_Swipe_View_Test_Align_001(UISwipeView::ALIGN_LEFT); + UIKit_Swipe_View_Test_Align_001(UISwipeView::ALIGN_CENTER); + UIKit_Swipe_View_Test_Align_001(UISwipeView::ALIGN_RIGHT); + + UIKit_Swipe_View_Test_Ver_001(); + UIKit_Swipe_View_Test_Ver_002(); + UIKit_Swipe_View_Test_Remove_001(); + + return container_; +} + +void UITestUISwipeView::UIKit_Swipe_View_Test_Horizontal_001() +{ + if (container_ == nullptr) { + return; + } + UILabel* label = GetTitleLabel("UISwipeView水平滑动"); + container_->Add(label); + positionX_ = TEXT_DISTANCE_TO_LEFT_SIDE; + positionY_ = TEXT_DISTANCE_TO_TOP_SIDE; + label->SetPosition(positionX_, positionY_); + positionY_ += g_deltaCoordinateY2; + + UISwipeView* swipe = new UISwipeView(UISwipeView::HORIZONTAL); + swipe->SetStyle(STYLE_BACKGROUND_COLOR, Color::Red().full); + swipe->SetPosition(positionX_, positionY_, g_swipeW, g_swipeH); + swipe->SetBlankSize(100); // 100: is blank size + container_->Add(swipe); + UILabelButton* button1 = new UILabelButton(); + button1->SetPosition(0, 0, g_buttonW, g_buttonH); + button1->SetText("button1"); + swipe->Add(button1); + UILabelButton* button2 = new UILabelButton(); + button2->SetPosition(0, 0, g_buttonW, g_buttonH); + button2->SetText("button2"); + swipe->Add(button2); + SetLastPos(swipe); + positionY_ += g_swipeH; +} + +void UITestUISwipeView::UIKit_Swipe_View_Test_Horizontal_002() +{ + if (container_ == nullptr) { + return; + } + UILabel* label = GetTitleLabel("UISwipeView循环水平滑动"); + container_->Add(label); + positionY_ += g_deltaCoordinateY; + label->SetPosition(positionX_, positionY_); + positionY_ += g_deltaCoordinateY2; + + UISwipeView* swipe = new UISwipeView(UISwipeView::HORIZONTAL); + swipe->SetStyle(STYLE_BACKGROUND_COLOR, Color::Red().full); + swipe->SetPosition(positionX_, positionY_, g_swipeW, g_swipeH); + swipe->SetLoopState(true); + swipe->SetAnimatorTime(100); // 100: mean animator drag time(ms) + container_->Add(swipe); + UILabelButton* button1 = new UILabelButton(); + button1->SetPosition(0, 0, g_buttonW, g_buttonH); + button1->SetText("button1"); + swipe->Add(button1); + UILabelButton* button2 = new UILabelButton(); + button2->SetPosition(0, 0, g_buttonW, g_buttonH); + button2->SetText("button2"); + swipe->Add(button2); + UILabelButton* button3 = new UILabelButton(); + button3->SetPosition(0, 0, g_buttonW, g_buttonH); + button3->SetText("button3"); + swipe->Add(button3); + SetLastPos(swipe); + positionY_ += g_swipeH; +} + +void UITestUISwipeView::UIKit_Swipe_View_Test_Ver_001() +{ + if (container_ == nullptr) { + return; + } + positionX_ = Screen::GetInstance().GetWidth() / 2 + TEXT_DISTANCE_TO_LEFT_SIDE; // 2: half of screen width + positionY_ = TEXT_DISTANCE_TO_TOP_SIDE; + UILabel* label = GetTitleLabel("UISwipeView垂直滑动"); + container_->Add(label); + positionY_ += g_deltaCoordinateY; + label->SetPosition(positionX_, positionY_); + positionY_ += g_deltaCoordinateY2; + + UISwipeView* swipe = new UISwipeView(UISwipeView::VERTICAL); + swipe->SetStyle(STYLE_BACKGROUND_COLOR, Color::Red().full); + swipe->SetPosition(positionX_, positionY_, g_swipeH, g_swipeW); + container_->Add(swipe); + UILabelButton* button1 = new UILabelButton(); + button1->SetPosition(0, 0, g_buttonH, g_buttonW); + button1->SetText("button1"); + swipe->Add(button1); + UILabelButton* button2 = new UILabelButton(); + button2->SetPosition(0, 0, g_buttonH, g_buttonW); + button2->SetText("button2"); + swipe->Add(button2); + SetLastPos(swipe); + positionY_ += g_swipeW + g_deltaCoordinateY; +} + +void UITestUISwipeView::UIKit_Swipe_View_Test_Ver_002() +{ + if (container_ == nullptr) { + return; + } + + UILabel* label = GetTitleLabel("UISwipeView循环垂直滑动"); + container_->Add(label); + label->SetPosition(positionX_, positionY_); + positionY_ += g_deltaCoordinateY2; + + UISwipeView* swipe = new UISwipeView(UISwipeView::VERTICAL); + swipe->SetStyle(STYLE_BACKGROUND_COLOR, Color::Red().full); + swipe->SetPosition(positionX_, positionY_, g_swipeH, g_swipeW); + swipe->SetLoopState(true); + swipe->SetAnimatorTime(100); // 100: is animator drag time(ms) + container_->Add(swipe); + UILabelButton* button1 = new UILabelButton(); + button1->SetPosition(0, 0, g_buttonH, g_buttonW); + button1->SetText("button1"); + swipe->Add(button1); + UILabelButton* button2 = new UILabelButton(); + button2->SetPosition(0, 0, g_buttonH, g_buttonW); + button2->SetText("button2"); + swipe->Add(button2); + UILabelButton* button3 = new UILabelButton(); + button3->SetPosition(0, 0, g_buttonH, g_buttonW); + button3->SetText("button3"); + swipe->Add(button3); + SetLastPos(swipe); + positionY_ += g_swipeW; +} + +void UITestUISwipeView::UIKit_Swipe_View_Test_Remove_001() +{ + if (container_ == nullptr) { + return; + } + UILabel* label = GetTitleLabel("UISwipeView增加和删除子节点"); + container_->Add(label); + positionY_ += g_deltaCoordinateY; + label->SetPosition(positionX_, positionY_); + positionY_ += g_deltaCoordinateY2; + + UISwipeView* swipe = new UISwipeView(UISwipeView::HORIZONTAL); + swipe->SetStyle(STYLE_BACKGROUND_COLOR, Color::Red().full); + swipe->SetPosition(positionX_, positionY_, g_swipeH, g_swipeW); + swipe->SetLoopState(true); + swipe->SetAnimatorTime(100); // 100: mean animator drag time(ms) + currentSwipe_ = swipe; + container_->Add(swipe); + + if (addBtnInHead_ == nullptr) { + addBtnInHead_ = new UILabelButton(); + } + if (addBtnInTail_ == nullptr) { + addBtnInTail_ = new UILabelButton(); + } + if (addBtnInMid_ == nullptr) { + addBtnInMid_ = new UILabelButton(); + } + if (removeHeadBtn_ == nullptr) { + removeHeadBtn_ = new UILabelButton(); + } + if (removeMidBtn_ == nullptr) { + removeMidBtn_ = new UILabelButton(); + } + if (removeAllBtn_ == nullptr) { + removeAllBtn_ = new UILabelButton(); + } + + positionX_ = positionX_ + swipe->GetWidth() + 20; // 20: is interval between button and swipe + SetUpButton(addBtnInHead_, "增加至头部 "); + SetUpButton(addBtnInTail_, "增加至尾部 "); + SetUpButton(addBtnInMid_, "增加至头部后 "); + SetUpButton(removeHeadBtn_, "删除头部节点 "); + SetUpButton(removeMidBtn_, "删除中间节点 "); + SetUpButton(removeAllBtn_, "删除全部节点 "); + + SetLastPos(swipe); +} + +void UITestUISwipeView::UIKit_Swipe_View_Test_Align_001(UISwipeView::AlignMode alignMode) +{ + static uint8_t divNum = 4; + if (container_ == nullptr) { + return; + } + + const char* leftTitle = "UISwipeView 子组件左对齐"; + const char* centerTitle = "UISwipeView 子组件Center对齐"; + const char* rightTitle = "UISwipeView 子组件右对齐"; + UILabel* label; + if (alignMode == UISwipeView::ALIGN_LEFT) { + label = GetTitleLabel(leftTitle); + } else if (alignMode == UISwipeView::ALIGN_RIGHT) { + label = GetTitleLabel(rightTitle); + } else { + label = GetTitleLabel(centerTitle); + } + + container_->Add(label); + label->SetPosition(positionX_, lastY_ + g_blank); + + UISwipeView* swipe = new UISwipeView(UISwipeView::HORIZONTAL); + swipe->SetStyle(STYLE_BACKGROUND_COLOR, Color::Red().full); + // 100: offset + swipe->SetPosition(positionX_, label->GetY() + g_blank + g_deltaCoordinateY, g_swipeW - 100, g_swipeH); + swipe->SetLoopState(true); + swipe->SetAnimatorTime(100); // 100: mean animator drag time(ms) + swipe->SetAlignMode(alignMode); + container_->Add(swipe); + UILabelButton* button1 = new UILabelButton(); + button1->SetPosition(0, 0, g_buttonW / divNum, g_buttonH / 2); // 2: half + button1->SetText("button1"); + swipe->Add(button1); + UILabelButton* button2 = new UILabelButton(); + button2->SetPosition(0, 0, g_buttonW / divNum, g_buttonH / 2); // 2: half + button2->SetText("button2"); + swipe->Add(button2); + UILabelButton* button3 = new UILabelButton(); + button3->SetPosition(0, 0, g_buttonW / divNum, g_buttonH / 2); // 2: half + button3->SetText("button3"); + swipe->Add(button3); + + UILabel* tmpLabel = nullptr; + const char* tmpOkTitle = "The result of GetAlignMode is OK."; + const char* tmpErrTitle = "The result of GetAlignMode is Error."; + uint8_t tmpAlignMode = swipe->GetAlignMode(); + if (tmpAlignMode == alignMode) { + tmpLabel = GetTitleLabel(tmpOkTitle); + } else { + tmpLabel = GetTitleLabel(tmpErrTitle); + } + tmpLabel->SetPosition(positionX_, 100, 250, 25); // 100: y, 250:width, 25:height + swipe->Add(tmpLabel); + + SetLastPos(swipe); +} + +bool UITestUISwipeView::OnClick(UIView& view, const ClickEvent& event) +{ + if (currentSwipe_ == nullptr) { + return true; + } + if (&view == addBtnInHead_) { + UILabelButton* btn = new UILabelButton(); + btn->SetPosition(0, 0, g_buttonH, g_buttonW); + btn->SetText(std::to_string(btnNum_).c_str()); + currentSwipe_->Insert(nullptr, btn); + } else if (&view == addBtnInTail_) { + UILabelButton* btn = new UILabelButton(); + btn->SetPosition(0, 0, g_buttonH, g_buttonW); + btn->SetText(std::to_string(btnNum_).c_str()); + currentSwipe_->Add(btn); + } else if (&view == addBtnInMid_) { + UILabelButton* btn = new UILabelButton(); + btn->SetPosition(0, 0, g_buttonH, g_buttonW); + btn->SetText(std::to_string(btnNum_).c_str()); + currentSwipe_->Insert(currentSwipe_->GetChildrenHead(), btn); + } else if (&view == removeHeadBtn_) { + currentSwipe_->Remove(currentSwipe_->GetChildrenHead()); + } else if (&view == removeMidBtn_) { + UIView* view = currentSwipe_->GetViewByIndex(1); + currentSwipe_->Remove(view); + } else if (&view == removeAllBtn_) { + currentSwipe_->RemoveAll(); + } + currentSwipe_->Invalidate(); + btnNum_++; + return true; +} + +void UITestUISwipeView::SetUpButton(UILabelButton* btn, const char* title) +{ + if (btn == nullptr) { + return; + } + container_->Add(btn); + btn->SetPosition(positionX_, positionY_, BUTTON_WIDHT2, BUTTON_HEIGHT2); + positionY_ += btn->GetHeight() + 10; // 10: increase y-coordinate + btn->SetText(title); + btn->SetFont(DEFAULT_VECTOR_FONT_FILENAME, BUTTON_LABEL_SIZE); + btn->SetOnClickListener(this); + btn->SetStyleForState(STYLE_BORDER_RADIUS, BUTTON_STYLE_BORDER_RADIUS_VALUE, UIButton::RELEASED); + btn->SetStyleForState(STYLE_BORDER_RADIUS, BUTTON_STYLE_BORDER_RADIUS_VALUE, UIButton::PRESSED); + btn->SetStyleForState(STYLE_BORDER_RADIUS, BUTTON_STYLE_BORDER_RADIUS_VALUE, UIButton::INACTIVE); + btn->SetStyleForState(STYLE_BACKGROUND_COLOR, BUTTON_STYLE_BACKGROUND_COLOR_VALUE, UIButton::RELEASED); + btn->SetStyleForState(STYLE_BACKGROUND_COLOR, BUTTON_STYLE_BACKGROUND_COLOR_VALUE, UIButton::PRESSED); + btn->SetStyleForState(STYLE_BACKGROUND_COLOR, BUTTON_STYLE_BACKGROUND_COLOR_VALUE, UIButton::INACTIVE); + container_->Invalidate(); +} + +void UITestUISwipeView::SetLastPos(UIView* view) +{ + if (view == nullptr) { + return; + } + lastX_ = view->GetX(); + lastY_ = view->GetY() + view->GetHeight(); +} +} // namespace OHOS diff --git a/test/uitest/test_ui_swipe_view/ui_test_ui_swipe_view.h b/test/uitest/test_ui_swipe_view/ui_test_ui_swipe_view.h new file mode 100755 index 0000000..116cf08 --- /dev/null +++ b/test/uitest/test_ui_swipe_view/ui_test_ui_swipe_view.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef UI_TEST_UI_SWIPE_VIEW_H +#define UI_TEST_UI_SWIPE_VIEW_H + +#include "components/ui_label_button.h" +#include "components/ui_scroll_view.h" +#include "components/ui_swipe_view.h" +#include "ui_test.h" + +namespace OHOS { +class UITestUISwipeView : public UITest, UIView::OnClickListener { +public: + UITestUISwipeView() {} + ~UITestUISwipeView() {} + void SetUp() override; + void TearDown() override; + const UIView* GetTestView() override; + bool OnClick(UIView& view, const ClickEvent& event) override; + + void UIKit_Swipe_View_Test_Horizontal_001(); + void UIKit_Swipe_View_Test_Horizontal_002(); + void UIKit_Swipe_View_Test_Ver_001(); + void UIKit_Swipe_View_Test_Ver_002(); + void UIKit_Swipe_View_Test_Remove_001(); + void UIKit_Swipe_View_Test_Align_001(UISwipeView::AlignMode alignMode); + +private: + void SetUpButton(UILabelButton* btn, const char* title); + void SetLastPos(UIView* view); + UIScrollView* container_ = nullptr; + UISwipeView* currentSwipe_ = nullptr; + UILabelButton* addBtnInHead_ = nullptr; + UILabelButton* addBtnInTail_ = nullptr; + UILabelButton* addBtnInMid_ = nullptr; + UILabelButton* removeHeadBtn_ = nullptr; + UILabelButton* removeMidBtn_ = nullptr; + UILabelButton* removeAllBtn_ = nullptr; + + int16_t lastX_ = 0; + int16_t lastY_ = 0; + int16_t btnNum_ = 0; +}; +} // namespace OHOS +#endif // UI_TEST_UI_SWIPE_VIEW_H diff --git a/test/uitest/test_vector_font/ui_test_vector_font.cpp b/test/uitest/test_vector_font/ui_test_vector_font.cpp new file mode 100755 index 0000000..906756b --- /dev/null +++ b/test/uitest/test_vector_font/ui_test_vector_font.cpp @@ -0,0 +1,322 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "ui_test_vector_font.h" +#if ENABLE_VECTOR_FONT +#include + +#include "common/screen.h" +#include "components/ui_label.h" +#if ENABLE_MULTI_FONT +#include "font/ui_multi_font_manager.h" +#endif +namespace { +const int16_t GAP = 5; +const int16_t TITLE_HEIGHT = 29; +const uint16_t LABEL_WIDTH = 400; +const uint16_t LABEL_HEIGHT = 50; +const uint16_t BUF_SIZE = 200; +const uint16_t LANGUAGE_FILE_ID_MAX = 9; +const char* HYQIHEI_65S = "HYQiHei-65S.otf"; +const char* NOTONASKHARABIC_REGULAR = "NotoNaskhArabic-Regular.ttf"; +const char* ROBOTOCONDENSED_REGULAR = "RobotoCondensed-Regular.ttf"; +const char* NOTOSANSCJKJP_REGULAR = "NotoSansCJKjp-Regular.otf"; +const char* NOTOSANSTHAI_REGULAR = "NotoSansThai-Regular.ttf"; +const char* NOTOSANSHEBREW_REGULAR = "NotoSansHebrew-Regular.ttf"; +const char* NOTOSANSDEVANAGARI_REGULAR = "NotoSansDevanagari-Regular.otf"; +const char* NOTOSANSMYANMAR_CONDENSED = "NotoSansMyanmar-Condensed.ttf"; +const char* NOTOSANSBENGALI_REGULAR = "NotoSansBengali-Regular.ttf"; +} // namespace +namespace OHOS { +void UITestVectorFont::SetUp() +{ + if (container_ == nullptr) { + container_ = new UIScrollView(); + container_->SetThrowDrag(true); + container_->SetHorizontalScrollState(false); + container_->Resize(Screen::GetInstance().GetWidth(), Screen::GetInstance().GetHeight() - BACK_BUTTON_HEIGHT); + positionX_ = 50; // 50: init position x + positionY_ = 5; // 5: init position y + } +} + +void UITestVectorFont::TearDown() +{ + DeleteChildren(container_); + container_ = nullptr; +} + +void UITestVectorFont::InnerTestTitle(const char* title) +{ + UILabel* titleLabel = new UILabel(); + UIFont::GetInstance()->RegisterFontInfo(DEFAULT_VECTOR_FONT_FILENAME); + titleLabel->SetPosition(TEXT_DISTANCE_TO_LEFT_SIDE, positionY_, Screen::GetInstance().GetWidth(), + TITLE_LABEL_DEFAULT_HEIGHT); + titleLabel->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); + titleLabel->SetText(title); + container_->Add(titleLabel); + positionY_ += TITLE_HEIGHT + GAP; +} + +UIView* UITestVectorFont::GetTestView() +{ + Font_FontEngine_Vector_Test_CH_Lang_001(); + Font_FontEngine_Vector_Test_JA_Lang_001(); + Font_FontEngine_Vector_Test_JA_Lang_002(); + Font_FontEngine_Vector_Test_KR_Lang_001(); + Font_FontEngine_Vector_Test_VI_Lang_001(); +#if ENABLE_MULTI_FONT + Font_FontEngine_MultiLanguage_Test_JA_Lang_001(); + Font_FontEngine_MultiLanguage_Test_JA_Lang_002(); + Font_FontEngine_MultiLanguage_Test_KR_Lang_001(); + Font_FontEngine_MultiLanguage_Test_VI_Lang_001(); + Font_FontEngine_MultiLanguage_Test_CS_Lang_001(); + Font_FontEngine_MultiLanguage_Test_EL_Lang_001(); + Font_FontEngine_MultiLanguage_Test_RO_Lang_001(); +#endif + return container_; +} + +void UITestVectorFont::Font_FontEngine_Vector_Test_CH_Lang_001() +{ + if (container_ != nullptr) { + InnerTestTitle("CH Language"); + UILabel* label = new UILabel(); + UIFont::GetInstance()->RegisterFontInfo(HYQIHEI_65S); + label->SetPosition(positionX_, positionY_); + label->Resize(LABEL_WIDTH, LABEL_HEIGHT); + label->SetLineBreakMode(UILabel::LINE_BREAK_MARQUEE); + label->SetFont(HYQIHEI_65S, 24); // 24 : size + label->SetText("测试中文"); + container_->Add(label); + positionY_ += LABEL_HEIGHT + GAP; + } +} + +void UITestVectorFont::Font_FontEngine_Vector_Test_JA_Lang_001() +{ + if (container_ != nullptr) { + InnerTestTitle("JA Language"); + UILabel* label = new UILabel(); + UIFont::GetInstance()->RegisterFontInfo(NOTOSANSCJKJP_REGULAR); + label->SetPosition(positionX_, positionY_); + label->Resize(LABEL_WIDTH, LABEL_HEIGHT); + label->SetLineBreakMode(UILabel::LINE_BREAK_MARQUEE); + label->SetFont(NOTOSANSCJKJP_REGULAR, 24); // 24 : size + label->SetText("ランニン"); + container_->Add(label); + positionY_ += LABEL_HEIGHT + GAP; + } +} + +void UITestVectorFont::Font_FontEngine_Vector_Test_JA_Lang_002() +{ + if (container_ != nullptr) { + InnerTestTitle("JA Language"); + UILabel* label = new UILabel(); + UIFont::GetInstance()->RegisterFontInfo(NOTOSANSCJKJP_REGULAR); + label->SetPosition(positionX_, positionY_); + label->Resize(LABEL_WIDTH, LABEL_HEIGHT); + label->SetLineBreakMode(UILabel::LINE_BREAK_MARQUEE); + label->SetFont(NOTOSANSCJKJP_REGULAR, 30); // 30 : size + label->SetText("ランニン"); + container_->Add(label); + positionY_ += LABEL_HEIGHT + GAP; + } +} + +void UITestVectorFont::Font_FontEngine_Vector_Test_KR_Lang_001() +{ + if (container_ != nullptr) { + InnerTestTitle("KR Language"); + UILabel* label = new UILabel(); + label->SetPosition(positionX_, positionY_); + label->Resize(LABEL_WIDTH, LABEL_HEIGHT); + label->SetLineBreakMode(UILabel::LINE_BREAK_MARQUEE); + UIFont::GetInstance()->RegisterFontInfo(NOTOSANSCJKJP_REGULAR); + label->SetFont(NOTOSANSCJKJP_REGULAR, 24); // 24 : size + label->SetText("韩语리기"); + container_->Add(label); + positionY_ += LABEL_HEIGHT + GAP; + } +} + +void UITestVectorFont::Font_FontEngine_Vector_Test_VI_Lang_001() +{ + if (container_ != nullptr) { + InnerTestTitle("VI Language"); + UIFont::GetInstance()->RegisterFontInfo(NOTOSANSCJKJP_REGULAR); + UIFont::GetInstance()->RegisterFontInfo(HYQIHEI_65S); + UILabel* label = new UILabel(); + label->SetPosition(positionX_, positionY_); + label->Resize(LABEL_WIDTH, LABEL_HEIGHT); + label->SetLineBreakMode(UILabel::LINE_BREAK_MARQUEE); + label->SetFont(ROBOTOCONDENSED_REGULAR, 24); // 24 : size + label->SetText("Kết thúc tập luyện?"); + container_->Add(label); + positionY_ += LABEL_HEIGHT + GAP; + } +} + +#if ENABLE_MULTI_FONT +void UITestVectorFont::Font_FontEngine_MultiLanguage_Test_JA_Lang_001() +{ + if (container_ != nullptr) { + InnerTestTitle("CH+JA Language"); + UIFont::GetInstance()->RegisterFontInfo(NOTOSANSCJKJP_REGULAR); + UIFont::GetInstance()->RegisterFontInfo(HYQIHEI_65S); + UIFont::GetInstance()->RegisterFontInfo(ROBOTOCONDENSED_REGULAR); + uint8_t findPath[] = {UIFont::GetInstance()->GetFontId(HYQIHEI_65S), + UIFont::GetInstance()->GetFontId(ROBOTOCONDENSED_REGULAR)}; + UIMultiFontManager::GetInstance()->SetSearchFontList(UIFont::GetInstance()->GetFontId(HYQIHEI_65S), findPath, + sizeof(findPath)); + UILabel* label = new UILabel(); + label->SetPosition(positionX_, positionY_); + label->Resize(LABEL_WIDTH, LABEL_HEIGHT); + label->SetLineBreakMode(UILabel::LINE_BREAK_MARQUEE); + label->SetFont(HYQIHEI_65S, 24); // 24 : size + label->SetText("日语ランニン"); + container_->Add(label); + positionY_ += LABEL_HEIGHT + GAP; + } +} + +void UITestVectorFont::Font_FontEngine_MultiLanguage_Test_JA_Lang_002() +{ + if (container_ != nullptr) { + InnerTestTitle("UnRegister JA Language"); + UILabel* label = new UILabel(); + label->SetPosition(positionX_, positionY_); + label->Resize(LABEL_WIDTH, LABEL_HEIGHT); + label->SetLineBreakMode(UILabel::LINE_BREAK_MARQUEE); + label->SetFont(NOTOSANSCJKJP_REGULAR, 24); // 24 : size + label->SetText("韩语日语리기ランニン"); + container_->Add(label); + positionY_ += LABEL_HEIGHT + GAP; + } +} + +void UITestVectorFont::Font_FontEngine_MultiLanguage_Test_KR_Lang_001() +{ + if (container_ != nullptr) { + InnerTestTitle("CH+KR Language"); + UIFont::GetInstance()->RegisterFontInfo(NOTOSANSCJKJP_REGULAR); + UIFont::GetInstance()->RegisterFontInfo(HYQIHEI_65S); + UIFont::GetInstance()->RegisterFontInfo(ROBOTOCONDENSED_REGULAR); + uint8_t findPath[] = {UIFont::GetInstance()->GetFontId(HYQIHEI_65S), + UIFont::GetInstance()->GetFontId(ROBOTOCONDENSED_REGULAR)}; + UIMultiFontManager::GetInstance()->SetSearchFontList(UIFont::GetInstance()->GetFontId(NOTOSANSCJKJP_REGULAR), + findPath, sizeof(findPath)); + UILabel* label = new UILabel(); + label->SetPosition(positionX_, positionY_); + label->Resize(LABEL_WIDTH, LABEL_HEIGHT); + label->SetLineBreakMode(UILabel::LINE_BREAK_MARQUEE); + label->SetFont(NOTOSANSCJKJP_REGULAR, 24); // 24 : size + label->SetText("韩语리기"); + container_->Add(label); + positionY_ += LABEL_HEIGHT + GAP; + } +} + +void UITestVectorFont::Font_FontEngine_MultiLanguage_Test_VI_Lang_001() +{ + if (container_ != nullptr) { + InnerTestTitle("CH+VI Language"); + UIFont::GetInstance()->RegisterFontInfo(NOTOSANSCJKJP_REGULAR); + UIFont::GetInstance()->RegisterFontInfo(HYQIHEI_65S); + UIFont::GetInstance()->RegisterFontInfo(ROBOTOCONDENSED_REGULAR); + uint8_t findPath4[] = {UIFont::GetInstance()->GetFontId(HYQIHEI_65S), + UIFont::GetInstance()->GetFontId(ROBOTOCONDENSED_REGULAR)}; + UIMultiFontManager::GetInstance()->SetSearchFontList(UIFont::GetInstance()->GetFontId(NOTOSANSCJKJP_REGULAR), + findPath4, sizeof(findPath4)); + UILabel* label = new UILabel(); + label->SetPosition(positionX_, positionY_); + label->Resize(LABEL_WIDTH, LABEL_HEIGHT); + label->SetLineBreakMode(UILabel::LINE_BREAK_MARQUEE); + label->SetFont(NOTOSANSCJKJP_REGULAR, 24); // 24 : size + label->SetText("越南语Kết thúc tập luyện?"); + container_->Add(label); + positionY_ += LABEL_HEIGHT + GAP; + } +} + +void UITestVectorFont::Font_FontEngine_MultiLanguage_Test_CS_Lang_001() +{ + if (container_ != nullptr) { + InnerTestTitle("CH+CS Language"); + UIFont::GetInstance()->RegisterFontInfo(NOTOSANSCJKJP_REGULAR); + UIFont::GetInstance()->RegisterFontInfo(HYQIHEI_65S); + UIFont::GetInstance()->RegisterFontInfo(ROBOTOCONDENSED_REGULAR); + uint8_t findPath4[] = {UIFont::GetInstance()->GetFontId(HYQIHEI_65S), + UIFont::GetInstance()->GetFontId(ROBOTOCONDENSED_REGULAR)}; + UIMultiFontManager::GetInstance()->SetSearchFontList(UIFont::GetInstance()->GetFontId(NOTOSANSCJKJP_REGULAR), + findPath4, sizeof(findPath4)); + UILabel* label = new UILabel(); + label->SetPosition(positionX_, positionY_); + label->Resize(LABEL_WIDTH, LABEL_HEIGHT); + label->SetLineBreakMode(UILabel::LINE_BREAK_MARQUEE); + label->SetFont(NOTOSANSCJKJP_REGULAR, 24); // 24 : size + label->SetText("捷克语sledování tepové frekvence"); + container_->Add(label); + positionY_ += LABEL_HEIGHT + GAP; + } +} + +void UITestVectorFont::Font_FontEngine_MultiLanguage_Test_EL_Lang_001() +{ + if (container_ != nullptr) { + InnerTestTitle("CH+EL Language"); + UIFont::GetInstance()->RegisterFontInfo(NOTOSANSCJKJP_REGULAR); + UIFont::GetInstance()->RegisterFontInfo(HYQIHEI_65S); + UIFont::GetInstance()->RegisterFontInfo(ROBOTOCONDENSED_REGULAR); + uint8_t findPath4[] = {UIFont::GetInstance()->GetFontId(HYQIHEI_65S), + UIFont::GetInstance()->GetFontId(ROBOTOCONDENSED_REGULAR)}; + UIMultiFontManager::GetInstance()->SetSearchFontList(UIFont::GetInstance()->GetFontId(NOTOSANSCJKJP_REGULAR), + findPath4, sizeof(findPath4)); + UILabel* label = new UILabel(); + label->SetPosition(positionX_, positionY_); + label->Resize(LABEL_WIDTH, LABEL_HEIGHT); + label->SetLineBreakMode(UILabel::LINE_BREAK_MARQUEE); + label->SetFont(NOTOSANSCJKJP_REGULAR, 24); // 24 : size + label->SetText("西班牙España"); + container_->Add(label); + positionY_ += LABEL_HEIGHT + GAP; + } +} + +void UITestVectorFont::Font_FontEngine_MultiLanguage_Test_RO_Lang_001() +{ + if (container_ != nullptr) { + InnerTestTitle("RO Language"); + UIFont::GetInstance()->RegisterFontInfo(NOTOSANSCJKJP_REGULAR); + UIFont::GetInstance()->RegisterFontInfo(HYQIHEI_65S); + UIFont::GetInstance()->RegisterFontInfo(ROBOTOCONDENSED_REGULAR); + uint8_t findPath4[] = {UIFont::GetInstance()->GetFontId(HYQIHEI_65S), + UIFont::GetInstance()->GetFontId(ROBOTOCONDENSED_REGULAR)}; + UIMultiFontManager::GetInstance()->SetSearchFontList(UIFont::GetInstance()->GetFontId(NOTOSANSCJKJP_REGULAR), + findPath4, sizeof(findPath4)); + UILabel* label = new UILabel(); + label->SetPosition(positionX_, positionY_); + label->Resize(LABEL_WIDTH, LABEL_HEIGHT); + label->SetLineBreakMode(UILabel::LINE_BREAK_MARQUEE); + label->SetFont(NOTOSANSCJKJP_REGULAR, 24); // 24 : size + label->SetText("罗马尼亚Română"); + container_->Add(label); + positionY_ += LABEL_HEIGHT + GAP; + } +} +#endif +} // namespace OHOS +#endif // ENABLE_VECTOR_FONT diff --git a/test/uitest/test_vector_font/ui_test_vector_font.h b/test/uitest/test_vector_font/ui_test_vector_font.h new file mode 100755 index 0000000..931b714 --- /dev/null +++ b/test/uitest/test_vector_font/ui_test_vector_font.h @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef UI_TEST_VECTOR_FONT_H +#define UI_TEST_VECTOR_FONT_H + +#include "graphic_config.h" +#if ENABLE_VECTOR_FONT +#include "ui_test.h" +#include "components/ui_scroll_view.h" +#include "font/ui_font.h" +#include + +namespace OHOS { +class UITestVectorFont : public UITest { +public: + UITestVectorFont() {} + ~UITestVectorFont() {} + void SetUp() override; + void TearDown() override; + UIView* GetTestView() override; + void Font_FontEngine_Vector_Test_CH_Lang_001(); + void Font_FontEngine_Vector_Test_JA_Lang_001(); + void Font_FontEngine_Vector_Test_JA_Lang_002(); + void Font_FontEngine_Vector_Test_KR_Lang_001(); + void Font_FontEngine_Vector_Test_VI_Lang_001(); +#if ENABLE_MULTI_FONT + /** + * @brief Test JA language + */ + void Font_FontEngine_MultiLanguage_Test_JA_Lang_001(); + + /** + * @brief Test UnRegister JA language + */ + void Font_FontEngine_MultiLanguage_Test_JA_Lang_002(); + + /** + * @brief Test KR language + */ + void Font_FontEngine_MultiLanguage_Test_KR_Lang_001(); + + /** + * @brief Test VI language + */ + void Font_FontEngine_MultiLanguage_Test_VI_Lang_001(); + + /** + * @brief Test CS language + */ + void Font_FontEngine_MultiLanguage_Test_CS_Lang_001(); + + /** + * @brief Test EL language + */ + void Font_FontEngine_MultiLanguage_Test_EL_Lang_001(); + + /** + * @brief Test RO language + */ + void Font_FontEngine_MultiLanguage_Test_RO_Lang_001(); +#endif +private: + UIScrollView* container_ = nullptr; + void InnerTestTitle(const char* title); + int16_t xPos = 50; // 50: x initial position + int16_t yPos = 5; // 5 : y initial position +}; +} // namespace OHOS +#endif // ENABLE_VECTOR_FONT +#endif // UI_TEST_VECTOR_FONT_H diff --git a/test/uitest/test_video/ui_test_video.cpp b/test/uitest/test_video/ui_test_video.cpp new file mode 100755 index 0000000..132c758 --- /dev/null +++ b/test/uitest/test_video/ui_test_video.cpp @@ -0,0 +1,333 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "ui_test_video.h" +#include "securec.h" +#include "test_resource_config.h" +#ifndef VERSION_LITE +namespace OHOS { +void UITestVideo::SetUp() +{ + if (container_ == nullptr) { + container_ = new UIScrollView(); + container_->Resize(Screen::GetInstance().GetWidth(), Screen::GetInstance().GetHeight() - 30); // 30:offset + } +} + +void UITestVideo::TearDown() +{ + if (container_ != nullptr) { + container_->RemoveAll(); + delete container_; + container_ = nullptr; + } + if (video_ != nullptr) { + video_->Stop(); + video_->Reset(); + delete video_; + video_ = nullptr; + } + if (infoLabel_ != nullptr) { + delete infoLabel_; + infoLabel_ = nullptr; + } + if (testVideoListener_ != nullptr) { + delete testVideoListener_; + testVideoListener_ = nullptr; + } + DeleteTestButtons(); +} + +void UITestVideo::DeleteTestButtons() +{ + if (loopButton_ != nullptr) { + delete loopButton_; + loopButton_ = nullptr; + } + if (totleTimeButton_ != nullptr) { + delete totleTimeButton_; + totleTimeButton_ = nullptr; + } + if (volButtonAdd_ != nullptr) { + delete volButtonAdd_; + volButtonAdd_ = nullptr; + } + if (volButtonSub_ != nullptr) { + delete volButtonSub_; + volButtonSub_ = nullptr; + } + if (rewindButtonAdd_ != nullptr) { + delete rewindButtonAdd_; + rewindButtonAdd_ = nullptr; + } + if (rewindButtonSub_ != nullptr) { + delete rewindButtonSub_; + rewindButtonSub_ = nullptr; + } + if (playButton_ != nullptr) { + delete playButton_; + playButton_ = nullptr; + } + if (pauseButton_ != nullptr) { + delete pauseButton_; + pauseButton_ = nullptr; + } + if (stopButton_ != nullptr) { + delete stopButton_; + stopButton_ = nullptr; + } + if (resetButton_ != nullptr) { + delete resetButton_; + resetButton_ = nullptr; + } +} + +void UITestVideo::SetupTestButton(UILabelButton* button, const char* text) +{ + if (button != nullptr) { + int16_t buttonWidth = 60; // 60:button width + int16_t buttonHeight = 40; // 40:button height + button->SetText(text); + button->Resize(buttonWidth, buttonHeight); + button->SetOnClickListener(this); + } +} + +void UITestVideo::InitTestButtons() +{ + int16_t posX1 = Screen::GetInstance().GetWidth() - 160; // 160:posX1 offset + int16_t posX2 = Screen::GetInstance().GetWidth() - 80; // 80:posX2 offset + + loopButton_ = new UILabelButton(); + loopButton_->SetPosition(posX1, 50); // 50:position y + SetupTestButton(loopButton_, "loop"); + + totleTimeButton_ = new UILabelButton(); + totleTimeButton_->SetPosition(posX2, 50); // 50:position y + SetupTestButton(totleTimeButton_, "time"); + + volButtonAdd_ = new UILabelButton(); + volButtonAdd_->SetPosition(posX1, 100); // 100:position y + SetupTestButton(volButtonAdd_, "vol+"); + + volButtonSub_ = new UILabelButton(); + volButtonSub_->SetPosition(posX2, 100); // 100:position y + SetupTestButton(volButtonSub_, "vol-"); + + rewindButtonAdd_ = new UILabelButton(); + rewindButtonAdd_->SetPosition(posX1, 150); // 150:position y + SetupTestButton(rewindButtonAdd_, "pos+"); + + rewindButtonSub_ = new UILabelButton(); + rewindButtonSub_->SetPosition(posX2, 150); // 150:position y + SetupTestButton(rewindButtonSub_, "pos-"); + + playButton_ = new UILabelButton(); + playButton_->SetPosition(posX1, 200); // 200:position y + SetupTestButton(playButton_, "play"); + + pauseButton_ = new UILabelButton(); + pauseButton_->SetPosition(posX2, 200); // 200:position y + SetupTestButton(pauseButton_, "pause"); + + stopButton_ = new UILabelButton(); + stopButton_->SetPosition(posX1, 250); // 250:position y + SetupTestButton(stopButton_, "stop"); + + resetButton_ = new UILabelButton(); + resetButton_->SetPosition(posX2, 250); // 250:position y + SetupTestButton(resetButton_, "reset"); +} + +UIView* UITestVideo::GetTestView() +{ + if (video_ == nullptr) { + UIKit_UIVideo_Test_SetVideo_001(); + } + return container_; +} + +void UITestVideo::UIKit_UIVideo_Test_SetVideo_001() +{ + if (container_ != nullptr) { + if (video_ == nullptr) { + video_ = new UIVideo(); + } + + infoLabel_ = new UILabel; + infoLabel_->SetPosition(20, 60); // 20:position x 60:position y + infoLabel_->Resize(200, 40); // 200:label width 40:label height + + if (!video_->SetSrc(VIDEO_SOURCE_DIRECTORY)) { + infoLabel_->SetText("SetSrc error"); + return; + } + video_->SetPosition(0, 0); + video_->Resize(Screen::GetInstance().GetWidth(), Screen::GetInstance().GetHeight()); + if (!video_->Prepare()) { + infoLabel_->SetText("Prepare error"); + return; + } + + testVideoListener_ = new TestVideoListener(); + testVideoListener_->SetInfoLabel(infoLabel_); + video_->SetVideoPlayerListener(testVideoListener_); + + InitTestButtons(); + container_->Add(video_); + container_->Add(infoLabel_); + container_->Add(loopButton_); + container_->Add(totleTimeButton_); + container_->Add(volButtonAdd_); + container_->Add(volButtonSub_); + container_->Add(rewindButtonAdd_); + container_->Add(rewindButtonSub_); + container_->Add(playButton_); + container_->Add(pauseButton_); + container_->Add(stopButton_); + container_->Add(resetButton_); + + if (!video_->Play()) { + infoLabel_->SetText("Play error"); + return; + } + video_->ShowController(true); + } +} + +void UITestVideo::DealClickLoopButton() const +{ + if ((video_ == nullptr) || (infoLabel_ == nullptr)) { + return; + } + if (video_->IsSingleLooping()) { + if (video_->EnableSingleLooping(false)) { + infoLabel_->SetText("single"); + } else { + infoLabel_->SetText("single error"); + } + } else { + if (video_->EnableSingleLooping(true)) { + infoLabel_->SetText("loop"); + } else { + infoLabel_->SetText("loop error"); + } + } +} + +bool UITestVideo::OnClick(UIView &view, const ClickEvent& event) +{ + if ((video_ == nullptr) || (infoLabel_ == nullptr)) { + return true; + } + if (&view == loopButton_) { + DealClickLoopButton(); + } else if (&view == totleTimeButton_) { + int64_t duration = 0; + if (video_->GetDuration(duration)) { + char buf[10] = {0}; // 10:buf size + if (sprintf_s(buf, sizeof(buf), "%lld", duration) < 0) { + return true; + } + infoLabel_->SetText(&buf[0]); + } else { + infoLabel_->SetText("GetDuration error"); + } + } else if (&view == volButtonAdd_) { + if (video_->SetVolume(0.8, 0.8)) { // 0.8:left volume 0.8:right volume + infoLabel_->SetText("volume 0.8"); + } else { + infoLabel_->SetText("SetVolume error"); + } + } else if (&view == volButtonSub_) { + if (video_->SetVolume(0, 0)) { + infoLabel_->SetText("volume 0"); + } else { + infoLabel_->SetText("SetVolume error"); + } + } else { + return OnClick1(view, event); + } + return true; +} + +bool UITestVideo::OnClick1(UIView &view, const ClickEvent& event) +{ + if ((video_ == nullptr) || (infoLabel_ == nullptr)) { + return true; + } + if (&view == rewindButtonAdd_) { + int64_t time = 0; + if (video_->GetCurrentTime(time)) { + if (video_->Rewind(time + 3000)) { // 3000:rewind add ms + infoLabel_->SetText("Rewind + 3000"); + } else { + infoLabel_->SetText("Rewind error"); + } + } else { + infoLabel_->SetText("GetCurrentTime error"); + } + } else if (&view == rewindButtonSub_) { + int64_t time = 0; + if (video_->GetCurrentTime(time)) { + if (video_->Rewind(time - 3000)) { // 3000:rewind sub ms + infoLabel_->SetText("Rewind - 3000"); + } else { + infoLabel_->SetText("Rewind error"); + } + } else { + infoLabel_->SetText("GetCurrentTime error"); + } + } else { + return OnClick2(view, event); + } + return true; +} + +bool UITestVideo::OnClick2(UIView &view, const ClickEvent& event) +{ + if ((video_ == nullptr) || (infoLabel_ == nullptr)) { + return true; + } + if (&view == playButton_) { + if (video_->Play()) { + infoLabel_->SetText("Play"); + } else { + infoLabel_->SetText("Play error"); + } + } else if (&view == pauseButton_) { + if (video_->Pause()) { + infoLabel_->SetText("Pause"); + } else { + infoLabel_->SetText("Pause error"); + } + } else if (&view == stopButton_) { + if (video_->Stop()) { + infoLabel_->SetText("Stop"); + } else { + infoLabel_->SetText("Stop error"); + } + } else if (&view == resetButton_) { + if (video_->Reset()) { + infoLabel_->SetText("Reset"); + } else { + infoLabel_->SetText("Reset error"); + } + } + return true; +} +} // namespace OHOS + +#endif // VERSION_LITE diff --git a/test/uitest/test_video/ui_test_video.h b/test/uitest/test_video/ui_test_video.h new file mode 100755 index 0000000..b47f56b --- /dev/null +++ b/test/uitest/test_video/ui_test_video.h @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef UI_TEST_VIDEO_H +#define UI_TEST_VIDEO_H + +#include "components/ui_label_button.h" +#include "components/ui_scroll_view.h" +#include "components/ui_video.h" +#include "ui_test.h" + +#ifndef VERSION_LITE +namespace OHOS { +class UITestVideo : public UITest, public UIView::OnClickListener { +public: + UITestVideo() {} + ~UITestVideo() {} + void SetUp() override; + void TearDown() override; + UIView* GetTestView() override; + bool OnClick(UIView &view, const ClickEvent& event) override; + bool OnClick1(UIView &view, const ClickEvent& event); + bool OnClick2(UIView &view, const ClickEvent& event); + void DealClickLoopButton() const; + void InitTestButtons(); + void SetupTestButton(UILabelButton* button, const char* text); + void DeleteTestButtons(); + void UIKit_UIVideo_Test_SetVideo_001(); + + class TestVideoListener : public UIVideo::VideoPlayerListener { + public: + TestVideoListener() {} + ~TestVideoListener() {} + + void OnPlaybackComplete() override + { + if (infoLabel_ != nullptr) { + infoLabel_->SetText("OnPlaybackComplete"); + } + } + + void OnError(int32_t errorType, int32_t errorCode) override + { + if (infoLabel_ != nullptr) { + infoLabel_->SetText("OnError"); + } + } + + void OnInfo(int type, int extra) override + { + if (infoLabel_ != nullptr) { + infoLabel_->SetText("OnInfo"); + } + } + + void OnVideoSizeChanged(int width, int height) override + { + if (infoLabel_ != nullptr) { + infoLabel_->SetText("OnVideoSizeChanged"); + } + } + + void OnRewindToComplete() override + { + if (infoLabel_ != nullptr) { + infoLabel_->SetText("OnRewindToComplete"); + } + } + + void OnPlaybackPause() override + { + if (infoLabel_ != nullptr) { + infoLabel_->SetText("OnPlaybackPause"); + } + } + + void OnPlaybackPlay() override + { + if (infoLabel_ != nullptr) { + infoLabel_->SetText("OnPlaybackPlay"); + } + } + + void OnPlaybackStop() override + { + if (infoLabel_ != nullptr) { + infoLabel_->SetText("OnPlaybackStop"); + } + } + + void SetInfoLabel(UILabel* label) + { + infoLabel_ = label; + } + + private: + UILabel* infoLabel_ = nullptr; + }; + +private: + UIScrollView* container_ = nullptr; + UIVideo* video_ = nullptr; + UILabel* infoLabel_ = nullptr; + UILabelButton* loopButton_ = nullptr; + UILabelButton* volButtonAdd_ = nullptr; + UILabelButton* volButtonSub_ = nullptr; + UILabelButton* rewindButtonAdd_ = nullptr; + UILabelButton* rewindButtonSub_ = nullptr; + UILabelButton* pauseButton_ = nullptr; + UILabelButton* playButton_ = nullptr; + UILabelButton* stopButton_ = nullptr; + UILabelButton* resetButton_ = nullptr; + UILabelButton* totleTimeButton_ = nullptr; + TestVideoListener* testVideoListener_ = nullptr; +}; +} // namespace OHOS +#endif // VERSION_LITE +#endif // UI_TEST_VIDEO_H diff --git a/test/uitest/test_view_percent/ui_test_view_percent.cpp b/test/uitest/test_view_percent/ui_test_view_percent.cpp new file mode 100755 index 0000000..6ebc7c6 --- /dev/null +++ b/test/uitest/test_view_percent/ui_test_view_percent.cpp @@ -0,0 +1,254 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "ui_test_view_percent.h" + +#include +#include +#include +#include "common/screen.h" +#include "components/ui_label.h" +#include "components/ui_label_button.h" +#include "layout/grid_layout.h" + +namespace OHOS { +namespace { + static int16_t g_widthPercent = 100; + const uint16_t LABEL_HEIGHT = 60; + const uint16_t DEFAULT_WIDITH = 80; + const uint16_t DEFAULT_HEIGHT = 60; + const uint16_t DEFAULT_ELEMENT_COUNT = 10; + const uint16_t DEFAULT_PERCENT = 10; + const uint16_t MAX_PERCENT = 100; + const float DEFAULT_PERCENT_INTERVAL = 100.0f; + const int16_t TEXT_H = 20; + const int16_t GAP = 10; + static int16_t g_view1WidthPercent = DEFAULT_PERCENT; + static int16_t g_view1HeightPercent = DEFAULT_PERCENT; + static int16_t g_view2WidthPercent = DEFAULT_PERCENT; + static int16_t g_view2HeightPercent = DEFAULT_PERCENT; +} + +void UITestViewPercent::SetUp() +{ + if (container_ == nullptr) { + InitContainer(); + } + viewGroup = new UIViewGroup(); + view1_ = new UIButton(); + view2_ = new UIView(); + view3_ = new UIView(); + resetfBtn_ = new UILabelButton(); + BiggerBtn_ = new UILabelButton(); + SmallerBtn_ = new UILabelButton(); + positionX_ = 20; // default start x-coordinate as 20 + positionY_ = 5; // default start y-coordinate as 5 +} + +void UITestViewPercent::TearDown() +{ + DeleteChildren(container_); + container_ = nullptr; +} + +UIView* UITestViewPercent::GetTestView() +{ + InitView(); + return container_; +} + +void UITestViewPercent::InitContainer() +{ + container_ = new UIScrollView(); + container_->SetThrowDrag(true); + container_->SetHorizontalScrollState(false); + container_->Resize(Screen::GetInstance().GetWidth(), Screen::GetInstance().GetHeight() - BACK_BUTTON_HEIGHT); +} + +void UITestViewPercent::InitView() +{ + if (container_ == nullptr) { + InitContainer(); + } + + UILabel* label = new UILabel(); + container_->Add(label); + positionY_ = TEXT_DISTANCE_TO_TOP_SIDE; + label->SetPosition(TEXT_DISTANCE_TO_LEFT_SIDE, positionY_, + Screen::GetInstance().GetWidth(), TITLE_LABEL_DEFAULT_HEIGHT); + label->SetText("Flex布局效果 "); + label->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); + positionY_ += (TEXT_H + GAP); + + flexLayout_ = new FlexLayout(); + container_->Add(flexLayout_); + InitFlexLayout(); + positionY_ += flexLayout_->GetHeight() + GAP; + + InitViewGroup(); + positionY_ += viewGroup->GetHeight() + GAP; + + GridLayout* gridLayout = new GridLayout(); + container_->Add(gridLayout); + gridLayout->Resize(260, 60); // 260: width; 60: height + gridLayout->SetLayoutDirection(LAYOUT_HOR); + gridLayout->SetPosition(0, positionY_); // 260: width; 60: height + // 2: half of screen width; 2: half of gridLayout + gridLayout->LayoutLeftOfParent(Screen::GetInstance().GetWidth() / 2 - gridLayout->GetWidth() / 2); + gridLayout->SetRows(1); // set gridlayout row as 1 + gridLayout->SetCols(3); // set gridlayout column as 3 + + SetUpButton(*gridLayout, *resetfBtn_, "reset"); + SetUpButton(*gridLayout, *BiggerBtn_, "Bigger"); + SetUpButton(*gridLayout, *SmallerBtn_, "Smaller"); + gridLayout->LayoutChildren(true); + container_->LayoutChildren(true); +} + +void UITestViewPercent::InitFlexLayout() +{ + positionY_ = VIEW_DISTANCE_TO_TOP_SIDE; + flexLayout_->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE, positionY_); + flexLayout_->SetWidthPercent(0.9f); // set default width percent as 0.9 + flexLayout_->SetHeightPercent(0.9f); // set default height percent as 0.9 + flexLayout_->SetStyle(STYLE_BORDER_COLOR, Color::White().full); + flexLayout_->SetStyle(STYLE_BORDER_OPA, HALF_OPA_OPAQUE); + flexLayout_->SetStyle(STYLE_BORDER_WIDTH, VIEW_STYLE_BORDER_WIDTH); + flexLayout_->SetStyle(STYLE_BORDER_RADIUS, VIEW_STYLE_BORDER_RADIUS); + flexLayout_->SetStyle(STYLE_BACKGROUND_OPA, 0); + for (int16_t i = 1; i <= DEFAULT_ELEMENT_COUNT; i++) { + AddElement(i); + } + flexLayout_->SetFlexWrap(1); + flexLayout_->SetLayoutDirection(LAYOUT_HOR); + flexLayout_->SetMajorAxisAlign(ALIGN_START); + flexLayout_->SetSecondaryAxisAlign(ALIGN_CENTER); + flexLayout_->LayoutChildren(); +} + +void UITestViewPercent::InitViewGroup() const +{ + container_->Add(viewGroup); + viewGroup->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE, positionY_); + viewGroup->SetWidthPercent(0.9f); // set default width percent as 0.9 + viewGroup->SetHeight(viewGroup->GetParent()->GetHeight()); + viewGroup->SetStyle(STYLE_BORDER_COLOR, Color::White().full); + viewGroup->SetStyle(STYLE_BORDER_OPA, HALF_OPA_OPAQUE); + viewGroup->SetStyle(STYLE_BORDER_WIDTH, VIEW_STYLE_BORDER_WIDTH); + viewGroup->SetStyle(STYLE_BORDER_RADIUS, VIEW_STYLE_BORDER_RADIUS); + viewGroup->SetStyle(STYLE_BACKGROUND_OPA, 0); + viewGroup->Add(view1_); + view1_->SetViewId("view1"); + view1_->SetPositionPercent(0.1, 0.1); // set view1 position percent x-percent=0.1, y-percent=0.1 + view1_->SetStyle(STYLE_BACKGROUND_COLOR, Color::Green().full); + view1_->SetStyle(STYLE_BACKGROUND_OPA, OPA_OPAQUE); + view1_->SetStyle(STYLE_BORDER_COLOR, Color::Black().full); + view1_->SetStyle(STYLE_BORDER_OPA, OPA_OPAQUE); + view1_->SetStyle(STYLE_BORDER_WIDTH, 1); // set border width 1 + view1_->SetStyle(STYLE_BORDER_RADIUS, 5); // set border radius 5 + view1_->SetHeightPercent(g_view1WidthPercent / DEFAULT_PERCENT_INTERVAL); + view1_->SetWidthPercent(g_view1HeightPercent / DEFAULT_PERCENT_INTERVAL); + + viewGroup->Add(view2_); + view2_->SetViewId("view2"); + view2_->SetStyle(STYLE_BACKGROUND_COLOR, Color::Blue().full); + view2_->SetStyle(STYLE_BACKGROUND_OPA, OPA_OPAQUE); + view2_->SetStyle(STYLE_BORDER_COLOR, Color::Blue().full); + view2_->SetStyle(STYLE_BORDER_OPA, OPA_OPAQUE); + view2_->SetStyle(STYLE_BORDER_WIDTH, 1); // set border width 1 + view2_->SetStyle(STYLE_BORDER_RADIUS, 5); // set border radius 5 + view2_->SetPositionPercent( + 0.3, 0.1, /* set view2 position percent x-percent=0.3, y-percent=0.1 */ + g_view2WidthPercent / DEFAULT_PERCENT_INTERVAL, g_view2HeightPercent / DEFAULT_PERCENT_INTERVAL); + + viewGroup->Add(view3_); + view3_->SetViewId("view3"); + view3_->SetStyle(STYLE_BACKGROUND_COLOR, Color::Red().full); + view3_->SetStyle(STYLE_BACKGROUND_OPA, OPA_OPAQUE); + view3_->SetStyle(STYLE_BORDER_COLOR, Color::Red().full); + view3_->SetStyle(STYLE_BORDER_OPA, OPA_OPAQUE); + view3_->SetStyle(STYLE_BORDER_WIDTH, 1); // set border width 1 + view3_->SetStyle(STYLE_BORDER_RADIUS, 5); // set border radius 5 + view3_->SetXPercent(0.5); // set view3 x-percent=0.5 + view3_->SetYPercent(0.1); // set view3 , y-percent=0.1 + view3_->SetWidthPercent(g_view2WidthPercent / DEFAULT_PERCENT_INTERVAL); + view3_->SetHeightPercent(g_view2HeightPercent / DEFAULT_PERCENT_INTERVAL); +} + +void UITestViewPercent::AddElement(int16_t index) +{ + if (flexLayout_ == nullptr) { + InitView(); + } + + UILabel* label = new UILabel(); + flexLayout_->Add(label); + float percent = DEFAULT_PERCENT / DEFAULT_PERCENT_INTERVAL; + label->SetWidthPercent(percent); + label->SetHeightPercent(percent); + label->SetText(std::to_string(index).c_str()); + label->SetFont("HYQiHei-65S.otf", 20); // set default font size as 20 + label->SetStyle(STYLE_TEXT_COLOR, Color::Black().full); + label->SetStyle(STYLE_BACKGROUND_COLOR, Color::White().full); + label->SetStyle(STYLE_BACKGROUND_OPA, OPA_OPAQUE); + label->SetStyle(STYLE_BORDER_COLOR, Color::Black().full); + label->SetStyle(STYLE_BORDER_OPA, OPA_OPAQUE); + label->SetStyle(STYLE_BORDER_WIDTH, 1); // set border width 1 + label->SetStyle(STYLE_BORDER_RADIUS, 5); // set border radius 5 + label->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); +} + +bool UITestViewPercent::OnClick(UIView& view, const ClickEvent& event) +{ + if (&view == resetfBtn_) { + g_view1HeightPercent = DEFAULT_PERCENT; + g_view1WidthPercent = DEFAULT_PERCENT; + g_view2HeightPercent = DEFAULT_PERCENT; + g_view2WidthPercent = DEFAULT_PERCENT; + view1_->ResizePercent(g_view1WidthPercent / DEFAULT_PERCENT_INTERVAL, + g_view1HeightPercent / DEFAULT_PERCENT_INTERVAL); + view2_->ResizePercent(g_view2WidthPercent / DEFAULT_PERCENT_INTERVAL, + g_view2HeightPercent / DEFAULT_PERCENT_INTERVAL); + g_widthPercent = DEFAULT_PERCENT; + flexLayout_->SetWidthPercent(g_widthPercent / DEFAULT_PERCENT_INTERVAL); + } else if (&view == BiggerBtn_) { + if (g_widthPercent < DEFAULT_PERCENT) { + g_widthPercent++; + flexLayout_->SetWidthPercent(g_widthPercent / DEFAULT_PERCENT_INTERVAL); + } + g_view1HeightPercent++; + g_view1WidthPercent++; + g_view2HeightPercent++; + g_view2WidthPercent++; + view1_->ResizePercent(g_view1WidthPercent / DEFAULT_PERCENT_INTERVAL, + g_view1HeightPercent / DEFAULT_PERCENT_INTERVAL); + view2_->ResizePercent(g_view2WidthPercent / DEFAULT_PERCENT_INTERVAL, + g_view2HeightPercent / DEFAULT_PERCENT_INTERVAL); + } else if (&view == SmallerBtn_) { + g_view1HeightPercent--; + g_view1WidthPercent--; + g_view2HeightPercent--; + g_view2WidthPercent--; + view1_->ResizePercent(g_view1WidthPercent / DEFAULT_PERCENT_INTERVAL, + g_view1HeightPercent / DEFAULT_PERCENT_INTERVAL); + view2_->ResizePercent(g_view2WidthPercent / DEFAULT_PERCENT_INTERVAL, + g_view2HeightPercent / DEFAULT_PERCENT_INTERVAL); + flexLayout_->SetWidthPercent((g_widthPercent--) / DEFAULT_PERCENT_INTERVAL); + } + view2_->GetParent()->Invalidate(); + return true; +} +} + diff --git a/test/uitest/test_view_percent/ui_test_view_percent.h b/test/uitest/test_view_percent/ui_test_view_percent.h new file mode 100755 index 0000000..591652e --- /dev/null +++ b/test/uitest/test_view_percent/ui_test_view_percent.h @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef UI_TEST_VIEW_PERCENT_H +#define UI_TEST_VIEW_PERCENT_H + +#include +#include "components/ui_label_button.h" +#include "components/ui_scroll_view.h" +#include "components/ui_view.h" +#include "components/ui_view_group.h" +#include "graphic_config.h" +#include "layout/flex_layout.h" +#include "layout/layout.h" +#include "ui_test.h" + +namespace OHOS { +class UITestViewPercent : public UITest, public UIView::OnClickListener { +public: + UITestViewPercent() {} + ~UITestViewPercent() {} + void SetUp() override; + void TearDown() override; + UIView* GetTestView() override; + bool OnClick(UIView& view, const ClickEvent& event) override; + +private: + void SetUpButton(Layout& controller, UILabelButton& btn, const std::string title) + { + controller.Add(&btn); + btn.Resize(BUTTON_WIDHT1, BUTTON_HEIGHT1); + btn.SetText(title.c_str()); + btn.SetFont(DEFAULT_VECTOR_FONT_FILENAME, BUTTON_LABEL_SIZE); + btn.SetOnClickListener(this); + btn.SetStyleForState(STYLE_BORDER_RADIUS, BUTTON_STYLE_BORDER_RADIUS_VALUE, UIButton::RELEASED); + btn.SetStyleForState(STYLE_BORDER_RADIUS, BUTTON_STYLE_BORDER_RADIUS_VALUE, UIButton::PRESSED); + btn.SetStyleForState(STYLE_BORDER_RADIUS, BUTTON_STYLE_BORDER_RADIUS_VALUE, UIButton::INACTIVE); + btn.SetStyleForState(STYLE_BACKGROUND_COLOR, BUTTON_STYLE_BACKGROUND_COLOR_VALUE, UIButton::RELEASED); + btn.SetStyleForState(STYLE_BACKGROUND_COLOR, BUTTON_STYLE_BACKGROUND_COLOR_VALUE, UIButton::PRESSED); + btn.SetStyleForState(STYLE_BACKGROUND_COLOR, BUTTON_STYLE_BACKGROUND_COLOR_VALUE, UIButton::INACTIVE); + } + void InitView(); + void InitFlexLayout(); + void InitViewGroup() const; + void InitContainer(); + void AddElement(int16_t index); + UIScrollView* container_ = nullptr; + FlexLayout* flexLayout_ = nullptr; + UIViewGroup* viewGroup = nullptr; + UIView* view1_ = nullptr; + UIView* view2_ = nullptr; + UIView* view3_ = nullptr; + UILabelButton* resetfBtn_ = nullptr; + UILabelButton* BiggerBtn_ = nullptr; + UILabelButton* SmallerBtn_ = nullptr; +}; +} // namespace OHOS +#endif // UI_TEST_VIEW_PERCENT_H + diff --git a/test/uitest/test_view_scale_rotate/ui_test_view_scale_rotate.cpp b/test/uitest/test_view_scale_rotate/ui_test_view_scale_rotate.cpp new file mode 100755 index 0000000..71262f3 --- /dev/null +++ b/test/uitest/test_view_scale_rotate/ui_test_view_scale_rotate.cpp @@ -0,0 +1,213 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "ui_test_view_scale_rotate.h" +#include "common/screen.h" +#include "components/ui_label.h" +#include "test_resource_config.h" + +namespace OHOS { +void UITestViewScaleRotate::SetUp() +{ + if (container_ == nullptr) { + container_ = new UIScrollView(); + container_->Resize(Screen::GetInstance().GetWidth(), Screen::GetInstance().GetHeight() - BACK_BUTTON_HEIGHT); + } + + if (list_ == nullptr) { + list_ = new ListLayout(UISwipeView::VERTICAL); + uint16_t width = Screen::GetInstance().GetWidth(); + uint16_t height = Screen::GetInstance().GetHeight(); + list_->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE, 0, width, height + 1); + container_->Add(list_); + } +} + +void UITestViewScaleRotate::TearDown() +{ + animator_.Stop(); + DeleteChildren(container_); + container_ = nullptr; + list_ = nullptr; +} + +UIView* UITestViewScaleRotate::GetTestView() +{ + UIKit_View_Scale_Rotate_Test_Label_001(); + UIKit_View_Scale_Rotate_Test_LabelButton_002(); + UIKit_View_Scale_Rotate_Test_Canvas_003(); + UIKit_View_Scale_Rotate_Test_UIBoxProgress_004(); + UIKit_View_Scale_Rotate_Test_UICircleProgress_005(); + UIKit_View_Scale_Rotate_Test_UIDigitalClock_006(); + UIKit_View_Scale_Rotate_Test_Group_007(); + + animator_.Start(); + return container_; +} + +void UITestViewScaleRotate::Callback(UIView* view) +{ + angleValue_++; + + if (scaleValue_.x_ < 0.2f) { + scaleStep_ = 0.01f; + } else if (scaleValue_.x_ > 1.5f) { + scaleStep_ = -0.01f; + } + scaleValue_.x_ += scaleStep_; + scaleValue_.y_ += scaleStep_; + + button1_->Rotate(angleValue_, VIEW_CENTER); + button1_->Scale(scaleValue_, VIEW_CENTER); + group1_->Rotate(angleValue_, GROUP_CENTER); + group1_->Scale(scaleValue_, GROUP_CENTER); + canvas_->Rotate(angleValue_, GROUP_CENTER); + canvas_->Scale(scaleValue_, GROUP_CENTER); + boxProgress_->Rotate(angleValue_, VIEW_CENTER); + boxProgress_->Scale(scaleValue_, VIEW_CENTER); + circleProgress_->Rotate(angleValue_, VIEW_CENTER); + circleProgress_->Scale(scaleValue_, VIEW_CENTER); + dClock_->Rotate(angleValue_, VIEW_CENTER); + dClock_->Scale(scaleValue_, VIEW_CENTER); + label_->Rotate(angleValue_, VIEW_CENTER); + label_->Scale(scaleValue_, VIEW_CENTER); +} + +void UITestViewScaleRotate::SetUpLabel(const char* title) const +{ + UILabel* label = new UILabel(); + label->SetPosition(TEXT_DISTANCE_TO_LEFT_SIDE, TEXT_DISTANCE_TO_TOP_SIDE, + Screen::GetInstance().GetWidth(), TITLE_LABEL_DEFAULT_HEIGHT); + label->SetText(title); + label->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); + list_->Add(label); +} + +void UITestViewScaleRotate::UIKit_View_Scale_Rotate_Test_Label_001() +{ + SetUpLabel("UILabel组件旋转 "); + UIViewGroup* group = new UIViewGroup(); + group->SetPosition(0, 0, GROUP_WIDHT, GROUP_HEIGHT); + label_ = new UILabel(); + label_->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE); + label_->SetText("Test UILabel"); + label_->SetPosition(100, 100, 200, 50); // 100: x 100: y 200: width 50: height + group->Add(label_); + list_->Add(group); +} + +void UITestViewScaleRotate::UIKit_View_Scale_Rotate_Test_LabelButton_002() +{ + SetUpLabel("UILabelButton组件旋转 "); + UIViewGroup* group = new UIViewGroup(); + group->SetPosition(0, 0, GROUP_WIDHT, GROUP_HEIGHT); + list_->Add(group); + button1_ = new UILabelButton(); + button1_->SetPosition(100, 100, 200, 50); // 100: x 100: y 200: width 50: height + button1_->SetText("Test UILabelButton"); + group->Add(button1_); +} + +void UITestViewScaleRotate::UIKit_View_Scale_Rotate_Test_Canvas_003() +{ + SetUpLabel("UICanvas组件旋转 "); + UIViewGroup* group = new UIViewGroup(); + group->SetPosition(0, 0, GROUP_WIDHT, GROUP_HEIGHT); + list_->Add(group); + canvas_ = new UICanvas(); + group->Add(canvas_); + + canvas_->SetPosition(0, 0, GROUP_WIDHT, GROUP_HEIGHT); + canvas_->SetStyle(STYLE_BACKGROUND_COLOR, Color::Gray().full); + + Paint paint; + paint.SetStrokeWidth(20); // 20: StrokeWidth + canvas_->DrawLine({150, 150}, {300, 300}, paint); // 150: x 150: y 300: x 300: y + + paint.SetStrokeColor(Color::Red()); + canvas_->DrawCurve({100, 50}, {150, 50}, {150, 50}, {150, 100}, paint); + canvas_->DrawRect({10, 10}, 50, 50, paint); // 10: x 10: y 50: width 50: height +} + +void UITestViewScaleRotate::UIKit_View_Scale_Rotate_Test_UIBoxProgress_004() +{ + SetUpLabel("UIBoxProgress组件旋转 "); + UIViewGroup* group = new UIViewGroup(); + group->SetPosition(0, 0, GROUP_WIDHT, GROUP_HEIGHT); + list_->Add(group); + boxProgress_ = new UIBoxProgress(); + + boxProgress_ = new UIBoxProgress(); + boxProgress_->EnableBackground(true); + boxProgress_->SetPosition(100, 100, 200, 50); // 100: x 100:y 200:width 50: height + boxProgress_->SetValue(80); // 80: value + boxProgress_->SetBackgroundStyle(STYLE_BACKGROUND_OPA, OPA_OPAQUE); + boxProgress_->SetBackgroundStyle(STYLE_BACKGROUND_COLOR, Color::Red().full); + group->Add(boxProgress_); +} + +void UITestViewScaleRotate::UIKit_View_Scale_Rotate_Test_UICircleProgress_005() +{ + SetUpLabel("UICircleProgress组件旋转 "); + UIViewGroup* group = new UIViewGroup(); + group->SetPosition(0, 0, GROUP_WIDHT, GROUP_HEIGHT); + list_->Add(group); + circleProgress_ = new UICircleProgress(); + circleProgress_->SetPosition(10, 10, 150, 150); // 10: x 10: y 150: width 150: height + circleProgress_->SetCenterPosition(75, 75); // 75: position x 75: position y + circleProgress_->SetRadius(50); // 50: radius + circleProgress_->SetValue(20); // 20: value + circleProgress_->SetStyle(STYLE_BACKGROUND_OPA, OPA_OPAQUE); + circleProgress_->SetStyle(STYLE_BACKGROUND_COLOR, Color::Yellow().full); + group->Add(circleProgress_); +} +void UITestViewScaleRotate::UIKit_View_Scale_Rotate_Test_UIDigitalClock_006() +{ + SetUpLabel("UIDigitalClock组件旋转 "); + UIViewGroup* group = new UIViewGroup(); + group->SetPosition(0, 0, GROUP_WIDHT, GROUP_HEIGHT); + list_->Add(group); + dClock_ = new UIDigitalClock(); + dClock_->SetPosition(10, 10, 150, 150); // 10: x 10:y 150: width 150: height + dClock_->SetFont(DEFAULT_VECTOR_FONT_FILENAME, 30); // 30: font size + dClock_->SetTime24Hour(7, 25, 50); // 7: hour, 25: minute, 50: second + group->Add(dClock_); +} + +void UITestViewScaleRotate::UIKit_View_Scale_Rotate_Test_Group_007() +{ + SetUpLabel("UIViewGroup组件旋转 "); + UIViewGroup* group = new UIViewGroup(); + group->SetPosition(0, 0, GROUP_WIDHT, GROUP_HEIGHT); + list_->Add(group); + + group1_ = new UIViewGroup(); + group1_->SetPosition(0, 0, GROUP_WIDHT, GROUP_HEIGHT); + group1_->SetStyle(STYLE_BACKGROUND_OPA, OPA_OPAQUE); + group1_->SetStyle(STYLE_BACKGROUND_COLOR, Color::Yellow().full); + group->Add(group1_); + + UISlider* slider = new UISlider(); + slider->SetPosition(10, 10, 200, 50); // 10: x 10: y 200: width 50: height + slider->SetValue(50); // 50: value + slider->SetDirection(UISlider::Direction::DIR_LEFT_TO_RIGHT); + group1_->Add(slider); + + UILabelButton* button = new UILabelButton(); + button->SetPosition(10, 100, 200, 50); // 10: x 100:y 200: width 50: height + button->SetText("test ViewGroup"); + group1_->Add(button); +} +} // namespace OHOS \ No newline at end of file diff --git a/test/uitest/test_view_scale_rotate/ui_test_view_scale_rotate.h b/test/uitest/test_view_scale_rotate/ui_test_view_scale_rotate.h new file mode 100755 index 0000000..17a6145 --- /dev/null +++ b/test/uitest/test_view_scale_rotate/ui_test_view_scale_rotate.h @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef UI_TEST_VIEW_SCALE_ROTATE_H +#define UI_TEST_VIEW_SCALE_ROTATE_H + +#include "components/ui_arc_label.h" +#include "components/ui_box_progress.h" +#include "components/ui_button.h" +#include "components/ui_canvas.h" +#include "components/ui_circle_progress.h" +#include "components/ui_digital_clock.h" +#include "components/ui_image_view.h" +#include "components/ui_label_button.h" +#include "components/ui_scroll_view.h" +#include "components/ui_slider.h" +#include "components/ui_swipe_view.h" +#include "layout/list_layout.h" +#include "ui_test.h" + +namespace OHOS { +class UITestViewScaleRotate : public UITest, public AnimatorCallback { +public: + UITestViewScaleRotate() + : animator_(this, nullptr, 1000, true) // 1000: the animator duration time is 1000ms + { + AnimatorManager::GetInstance()->Add(&animator_); + } + virtual ~UITestViewScaleRotate() + { + AnimatorManager::GetInstance()->Remove(&animator_); + } + void SetUp() override; + void TearDown() override; + UIView* GetTestView() override; + void Callback(UIView* view) override; + + void UIKit_View_Scale_Rotate_Test_Label_001(); + void UIKit_View_Scale_Rotate_Test_LabelButton_002(); + void UIKit_View_Scale_Rotate_Test_Canvas_003(); + void UIKit_View_Scale_Rotate_Test_UIBoxProgress_004(); + void UIKit_View_Scale_Rotate_Test_UICircleProgress_005(); + void UIKit_View_Scale_Rotate_Test_UIDigitalClock_006(); + void UIKit_View_Scale_Rotate_Test_Group_007(); + +private: + const int GROUP_WIDHT = 454; + const int GROUP_HEIGHT = 300; + const Vector2 VIEW_CENTER = {75, 75}; + const Vector2 GROUP_CENTER = {200, 200}; + + void SetUpLabel(const char* title) const; + + UIScrollView* container_ = nullptr; + ListLayout* list_ = nullptr; + int16_t angleValue_ = 0; + Vector2 scaleValue_ = {1.0f, 1.0f}; + float scaleStep_ = 0.01f; + + Animator animator_; + UILabel* label_ = nullptr; + UICanvas* canvas_ = nullptr; + UILabelButton* button1_ = nullptr; + UIBoxProgress* boxProgress_ = nullptr; + UICircleProgress* circleProgress_ = nullptr; + UIDigitalClock* dClock_ = nullptr; + UIViewGroup* group1_ = nullptr; +}; +} // namespace OHOS +#endif // UI_TEST_BOX_PROGRESS_H diff --git a/test/unittest/BUILD.gn b/test/unittest/BUILD.gn new file mode 100755 index 0000000..87ff009 --- /dev/null +++ b/test/unittest/BUILD.gn @@ -0,0 +1,287 @@ +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. +# 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. + +import("//build/lite/config/test.gni") + +group("lite_graphic_ui_test") { + if (ohos_build_type == "debug") { + deps = [ + ":graphic_test_animator", + ":graphic_test_axis", + ":graphic_test_button", + ":graphic_test_canvas", + ":graphic_test_clock", + ":graphic_test_common", + ":graphic_test_dfx", + ":graphic_test_dialog", + ":graphic_test_events", + ":graphic_test_font", + ":graphic_test_image", + ":graphic_test_label", + ":graphic_test_layout", + ":graphic_test_picker", + ":graphic_test_progress", + ":graphic_test_qrcode", + ":graphic_test_render", + ":graphic_test_themes", + ":graphic_test_video", + ":graphic_test_view", + ] + } +} + +config("graphic_test_config") { + include_dirs = [ + "../framework/include", + "//foundation/graphic/ui/frameworks", + "//foundation/graphic/surface/interfaces/kits", + "//third_party/bounds_checking_function/include", + "//third_party/freetype/include", + "//kernel/liteos_a/kernel/include/", + "//kernel/liteos_a/kernel/common", + "//foundation/distributedschedule/samgr_lite/interfaces/kits/registry", + "//foundation/distributedschedule/samgr_lite/interfaces/kits/samgr", + "//foundation/distributedschedule/samgr_lite/interfaces/kits/communication/broadcast", + "//foundation/multimedia/media_lite/interfaces/kits/player_lite", + "//foundation/multimedia/utils/lite/include", + ] + ldflags = [ + "-lstdc++", + "-Wl,-rpath-link=$ohos_root_path/$root_out_dir", + ] +} + +if (ohos_build_type == "debug") { + commonDeps = [ "//foundation/graphic/ui:ui" ] + unittest("graphic_test_animator") { + output_extension = "bin" + output_dir = "$root_out_dir/test/unittest/graphic" + configs = [ ":graphic_test_config" ] + deps = commonDeps + sources = [ + "animator/animator_unit_test.cpp", + "animator/easing_equation_unit_test.cpp", + "animator/interpolation_unit_test.cpp", + ] + } + + unittest("graphic_test_common") { + output_extension = "bin" + output_dir = "$root_out_dir/test/unittest/graphic" + configs = [ ":graphic_test_config" ] + deps = commonDeps + sources = [ + "common/hardware_acceleration_unit_test.cpp", + "common/screen_unit_test.cpp", + "common/text_unit_test.cpp", + ] + } + + unittest("graphic_test_events") { + output_extension = "bin" + output_dir = "$root_out_dir/test/unittest/graphic" + configs = [ ":graphic_test_config" ] + deps = commonDeps + sources = [ + "events/cancel_event_unit_test.cpp", + "events/click_event_unit_test.cpp", + "events/drag_event_unit_test.cpp", + "events/event_bubble_unit_test.cpp", + "events/event_unit_test.cpp", + "events/key_event_unit_test.cpp", + "events/long_press_event_unit_test.cpp", + "events/press_event_unit_test.cpp", + "events/release_event_unit_test.cpp", + "events/virtual_device_event_unit_test.cpp", + ] + } + + unittest("graphic_test_layout") { + output_extension = "bin" + output_dir = "$root_out_dir/test/unittest/graphic" + configs = [ ":graphic_test_config" ] + deps = commonDeps + sources = [ "layout/list_layout_unit_test.cpp" ] + } + + unittest("graphic_test_render") { + output_extension = "bin" + output_dir = "$root_out_dir/test/unittest/graphic" + configs = [ ":graphic_test_config" ] + deps = commonDeps + sources = [ "render/render_uni_test.cpp" ] + } + + unittest("graphic_test_themes") { + output_extension = "bin" + output_dir = "$root_out_dir/test/unittest/graphic" + configs = [ ":graphic_test_config" ] + deps = commonDeps + sources = [ "themes/theme_manager_unit_test.cpp" ] + } + + unittest("graphic_test_button") { + output_extension = "bin" + output_dir = "$root_out_dir/test/unittest/graphic" + configs = [ ":graphic_test_config" ] + deps = commonDeps + sources = [ + "components/ui_button_unit_test.cpp", + "components/ui_checkbox_unit_test.cpp", + "components/ui_label_button_unit_test.cpp", + "components/ui_radio_button_unit_test.cpp", + "components/ui_repeat_button_unit_test.cpp", + "components/ui_toggle_button_unit_test.cpp", + ] + } + + unittest("graphic_test_progress") { + output_extension = "bin" + output_dir = "$root_out_dir/test/unittest/graphic" + configs = [ ":graphic_test_config" ] + deps = commonDeps + sources = [ + "components/ui_abstract_progress_unit_test.cpp", + "components/ui_box_progress_unit_test.cpp", + "components/ui_circle_progress_unit_test.cpp", + ] + } + + unittest("graphic_test_clock") { + output_extension = "bin" + output_dir = "$root_out_dir/test/unittest/graphic" + configs = [ ":graphic_test_config" ] + deps = commonDeps + sources = [ + "components/ui_analog_clock_unit_test.cpp", + "components/ui_digital_clock_unit_test.cpp", + ] + } + + unittest("graphic_test_label") { + output_extension = "bin" + output_dir = "$root_out_dir/test/unittest/graphic" + configs = [ ":graphic_test_config" ] + deps = commonDeps + sources = [ + "components/ui_arc_label_unit_test.cpp", + "components/ui_label_unit_test.cpp", + ] + } + + unittest("graphic_test_axis") { + output_extension = "bin" + output_dir = "$root_out_dir/test/unittest/graphic" + configs = [ ":graphic_test_config" ] + deps = commonDeps + sources = [ "components/ui_axis_unit_test.cpp" ] + } + + unittest("graphic_test_canvas") { + output_extension = "bin" + output_dir = "$root_out_dir/test/unittest/graphic" + configs = [ ":graphic_test_config" ] + deps = commonDeps + sources = [ + "components/ui_canvas_unit_test.cpp", + "components/ui_chart_unit_test.cpp", + "components/ui_slider_unit_test.cpp", + ] + } + + unittest("graphic_test_image") { + output_extension = "bin" + output_dir = "$root_out_dir/test/unittest/graphic" + configs = [ ":graphic_test_config" ] + deps = commonDeps + sources = [ + "components/ui_image_animator_unit_test.cpp", + "components/ui_image_unit_test.cpp", + "image/image_load_unit_test.cpp", + ] + } + + unittest("graphic_test_picker") { + output_extension = "bin" + output_dir = "$root_out_dir/test/unittest/graphic" + configs = [ ":graphic_test_config" ] + deps = commonDeps + sources = [ + "components/ui_picker_unit_test.cpp", + "components/ui_time_picker_unit_test.cpp", + ] + } + + unittest("graphic_test_qrcode") { + output_extension = "bin" + output_dir = "$root_out_dir/test/unittest/graphic" + configs = [ ":graphic_test_config" ] + deps = commonDeps + sources = [ "components/ui_qrcode_unit_test.cpp" ] + } + + unittest("graphic_test_view") { + output_extension = "bin" + output_dir = "$root_out_dir/test/unittest/graphic" + configs = [ ":graphic_test_config" ] + deps = commonDeps + sources = [ + "components/ui_scroll_view_unit_test.cpp", + "components/ui_surface_view_unit_test.cpp", + "components/ui_swipe_view_unit_test.cpp", + "components/ui_view_group_unit_test.cpp", + "components/ui_view_unit_test.cpp", + ] + } + + unittest("graphic_test_video") { + output_extension = "bin" + output_dir = "$root_out_dir/test/unittest/graphic" + configs = [ ":graphic_test_config" ] + sources = [ "components/ui_video_unit_test.cpp" ] + deps = commonDeps + deps += [ + "//foundation/multimedia/media_lite/frameworks/player_lite:player_lite", + ] + } + + unittest("graphic_test_dfx") { + output_extension = "bin" + output_dir = "$root_out_dir/test/unittest/graphic" + configs = [ ":graphic_test_config" ] + deps = commonDeps + sources = [ "dfx/event_injector_unit_test.cpp" ] + } + + unittest("graphic_test_dialog") { + output_extension = "bin" + output_dir = "$root_out_dir/test/unittest/graphic" + configs = [ ":graphic_test_config" ] + deps = commonDeps + sources = [ "components/ui_dialog_unit_test.cpp" ] + } + + unittest("graphic_test_font") { + output_extension = "bin" + output_dir = "$root_out_dir/test/unittest/graphic" + configs = [ ":graphic_test_config" ] + deps = commonDeps + sources = [ "font/ui_font_unit_test.cpp" ] + } + + unittest("graphic_test_rotate") { + output_extension = "bin" + output_dir = "$root_out_dir/test/unittest/graphic" + configs = [ ":graphic_test_config" ] + deps = commonDeps + sources = [ "rotate/ui_rotate_input_unit_test.cpp" ] + } +} diff --git a/test/unittest/animator/animator_unit_test.cpp b/test/unittest/animator/animator_unit_test.cpp new file mode 100755 index 0000000..8d4103d --- /dev/null +++ b/test/unittest/animator/animator_unit_test.cpp @@ -0,0 +1,229 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "animator/animator.h" + +#include +#include +#include "animator/easing_equation.h" +#include "common/task_manager.h" + +using namespace testing::ext; +namespace OHOS { +namespace { + const int16_t START_POS = 0; + const int16_t END_POS = 100; + const uint16_t TIME = 300; +} +class TestAnimatorCallback : public AnimatorCallback { +public: + explicit TestAnimatorCallback(UIView* view) : view_(view), animator_(nullptr) {} + + virtual ~TestAnimatorCallback() + { + if (animator_ != nullptr) { + delete animator_; + animator_ = nullptr; + } + } + + bool Init() + { + if (animator_ == nullptr) { + animator_ = new Animator(this, view_, TIME, false); + if (animator_ == nullptr) { + return false; + } + return true; + } + return false; + } + + virtual void Callback(UIView* view) override + { + int16_t pos = EasingEquation::LinearEaseNone(START_POS, END_POS, animator_->GetRunTime(), animator_->GetTime()); + view_->SetX(pos); + } + + virtual void OnStop(UIView& view) override + { + EXPECT_EQ(view_->GetX(), END_POS); + } + + Animator* GetAnimator() const + { + return animator_; + } +protected: + UIView* view_; + Animator* animator_; +}; + + +class AnimatorTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + static Animator* animator_; +}; + +Animator* AnimatorTest::animator_ = nullptr; + +void AnimatorTest::SetUpTestCase(void) +{ + if (animator_ == nullptr) { + animator_ = new Animator(); + } +} + +void AnimatorTest::TearDownTestCase(void) +{ + if (animator_ != nullptr) { + delete animator_; + animator_ = nullptr; + } +} + +/** + * @tc.name: AnimatorGetState_001 + * @tc.desc: Verify Start function, equal. + * @tc.type: FUNC + * @tc.require: AR000DSMQM + */ +HWTEST_F(AnimatorTest, AnimatorGetState_001, TestSize.Level0) +{ + if (animator_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + animator_->Start(); + EXPECT_EQ(animator_->GetState(), Animator::START); + animator_->Stop(); + EXPECT_EQ(animator_->GetState(), Animator::STOP); + animator_->Pause(); + EXPECT_EQ(animator_->GetState(), Animator::PAUSE); + animator_->Resume(); + EXPECT_EQ(animator_->GetState(), Animator::START); +} + +/** + * @tc.name: AnimatorSetState_001 + * @tc.desc: Verify SetState function, equal. + * @tc.type: FUNC + * @tc.require: AR000DSMQM + */ +HWTEST_F(AnimatorTest, AnimatorSetState_001, TestSize.Level0) +{ + if (animator_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + animator_->SetState(Animator::START); + EXPECT_EQ(animator_->GetState(), Animator::START); + animator_->SetState(Animator::STOP); + EXPECT_EQ(animator_->GetState(), Animator::STOP); + animator_->SetState(Animator::PAUSE); + EXPECT_EQ(animator_->GetState(), Animator::PAUSE); +} + +/** + * @tc.name: AnimatorSetTime_001 + * @tc.desc: Verify SetTime function, equal. + * @tc.type: FUNC + * @tc.require: AR000DSMQM + */ +HWTEST_F(AnimatorTest, AnimatorSetTime_001, TestSize.Level0) +{ + if (animator_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + animator_->SetTime(TIME); + EXPECT_EQ(animator_->GetTime(), TIME); +} + +/** + * @tc.name: AnimatorSetRunTime_001 + * @tc.desc: Verify SetRunTime function, equal. + * @tc.type: FUNC + * @tc.require: AR000DSMQM + */ +HWTEST_F(AnimatorTest, AnimatorSetRunTime_001, TestSize.Level0) +{ + if (animator_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + animator_->SetRunTime(TIME); + EXPECT_EQ(animator_->GetRunTime(), TIME); +} + +/** + * @tc.name: AnimatorIsRepeat_001 + * @tc.desc: Verify IsRepeat function, equal. + * @tc.type: FUNC + * @tc.require: AR000DSMQM + */ +HWTEST_F(AnimatorTest, AnimatorIsRepeat_001, TestSize.Level0) +{ + if (animator_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + EXPECT_EQ(animator_->IsRepeat(), false); +} + +/** + * @tc.name: AnimatorManagerAddAndRemove_001 + * @tc.desc: Verify AddAndRemove function, equal. + * @tc.type: FUNC + * @tc.require: AR000DSMQM + */ +HWTEST_F(AnimatorTest, AnimatorManagerAddAndRemove_001, TestSize.Level1) +{ + UIView* view = new UIView(); + view->SetX(START_POS); + auto callback = new TestAnimatorCallback(view); + if (!callback->Init()) { + EXPECT_NE(0, 0); + return; + } + Animator* animator = callback->GetAnimator(); + AnimatorManager::GetInstance()->Init(); + AnimatorManager::GetInstance()->Add(animator); + animator->Start(); + EXPECT_EQ(animator->GetState(), Animator::START); + TaskManager::GetInstance()->SetTaskRun(true); + while (1) { + TaskManager::GetInstance()->TaskHandler(); + if (animator->GetState() == Animator::STOP) { + break; + } + } + + AnimatorManager::GetInstance()->Remove(animator); + view->SetX(START_POS); + animator->Start(); + EXPECT_EQ(animator->GetState(), Animator::START); + for (uint16_t i = 0; i < TIME; i++) { + TaskManager::GetInstance()->TaskHandler(); + } + EXPECT_EQ(view->GetX(), START_POS); + TaskManager::GetInstance()->SetTaskRun(false); + TaskManager::GetInstance()->Remove(AnimatorManager::GetInstance()); + delete callback; + delete view; +} +} // namespace OHOS \ No newline at end of file diff --git a/test/unittest/animator/easing_equation_unit_test.cpp b/test/unittest/animator/easing_equation_unit_test.cpp new file mode 100755 index 0000000..20e6574 --- /dev/null +++ b/test/unittest/animator/easing_equation_unit_test.cpp @@ -0,0 +1,340 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "animator/easing_equation.h" + +#include +#include + +using namespace testing::ext; +namespace OHOS { +namespace { + const int16_t START_POS = 0; + const int16_t END_POS = 100; + const int16_t DURATION_TIME = 4; +} + +class EasingEquationTest : public testing::Test { +public: + static void SetUpTestCase(void) {} + static void TearDownTestCase(void) {} +}; + +/** + * @tc.name: EasingEquationBackEaseIn_001 + * @tc.desc: Verify BackEaseIn and GetHeight function. + * @tc.type: FUNC + * @tc.require: AR000DSMQM + */ +HWTEST_F(EasingEquationTest, EasingEquationBackEaseIn_001, TestSize.Level1) +{ + const double overShoot = 2; + EasingEquation::SetBackOvershoot(overShoot); + uint16_t i = 0; + EXPECT_EQ(EasingEquation::BackEaseIn(START_POS, END_POS, i++, DURATION_TIME), 0); + EXPECT_EQ(EasingEquation::BackEaseIn(START_POS, END_POS, i++, DURATION_TIME), -7); // -7:the value for 1th s; + EXPECT_EQ(EasingEquation::BackEaseIn(START_POS, END_POS, i++, DURATION_TIME), -12); // -12:the value for 2th s; + EXPECT_EQ(EasingEquation::BackEaseIn(START_POS, END_POS, i++, DURATION_TIME), 14); // 14:the value for 3th s; + EXPECT_EQ(EasingEquation::BackEaseIn(START_POS, END_POS, i++, DURATION_TIME), END_POS); +} + +/** + * @tc.name: EasingEquationBackEaseOut_001 + * @tc.desc: Verify BackEaseOut and GetHeight function. + * @tc.type: FUNC + * @tc.require: AR000DSMQM + */ +HWTEST_F(EasingEquationTest, EasingEquationBackEaseOut_001, TestSize.Level1) +{ + uint16_t i = 0; + EXPECT_EQ(EasingEquation::BackEaseOut(START_POS, END_POS, i++, DURATION_TIME), 0); + EXPECT_EQ(EasingEquation::BackEaseOut(START_POS, END_POS, i++, DURATION_TIME), 85); // 85:the value for 1th s; + EXPECT_EQ(EasingEquation::BackEaseOut(START_POS, END_POS, i++, DURATION_TIME), 112); // 112:the value for 2th s; + EXPECT_EQ(EasingEquation::BackEaseOut(START_POS, END_POS, i++, DURATION_TIME), 107); // 107:the value for 3th s; + EXPECT_EQ(EasingEquation::BackEaseOut(START_POS, END_POS, i++, DURATION_TIME), END_POS); +} + +/** + * @tc.name: EasingEquationBackEaseInOut_001 + * @tc.desc: Verify BackEaseInOut and GetHeight function. + * @tc.type: FUNC + * @tc.require: AR000DSMQM + */ +HWTEST_F(EasingEquationTest, EasingEquationBackEaseInOut_001, TestSize.Level1) +{ + uint16_t i = 0; + EXPECT_EQ(EasingEquation::BackEaseInOut(START_POS, END_POS, i++, DURATION_TIME), 0); + EXPECT_EQ(EasingEquation::BackEaseInOut(START_POS, END_POS, i++, DURATION_TIME), -6); // -6:the value for 1th s; + EXPECT_EQ(EasingEquation::BackEaseInOut(START_POS, END_POS, i++, DURATION_TIME), 50); // 50:the value for 2th s; + EXPECT_EQ(EasingEquation::BackEaseInOut(START_POS, END_POS, i++, DURATION_TIME), 106); // 106:the value for 3th s; + EXPECT_EQ(EasingEquation::BackEaseInOut(START_POS, END_POS, i++, DURATION_TIME), END_POS); +} + +/** + * @tc.name: EasingEquationCircEaseIn_001 + * @tc.desc: Verify CircEaseIn and GetHeight function. + * @tc.type: FUNC + * @tc.require: AR000DSMQM + */ +HWTEST_F(EasingEquationTest, EasingEquationCircEaseIn_001, TestSize.Level1) +{ + uint16_t i = 0; + EXPECT_EQ(EasingEquation::CircEaseIn(START_POS, END_POS, i++, DURATION_TIME), 0); + EXPECT_EQ(EasingEquation::CircEaseIn(START_POS, END_POS, i++, DURATION_TIME), 3); // 3:the value for 1th s; + EXPECT_EQ(EasingEquation::CircEaseIn(START_POS, END_POS, i++, DURATION_TIME), 13); // 13:the value for 2th s; + EXPECT_EQ(EasingEquation::CircEaseIn(START_POS, END_POS, i++, DURATION_TIME), 33); // 33:the value for 3th s; + EXPECT_EQ(EasingEquation::CircEaseIn(START_POS, END_POS, i++, DURATION_TIME), END_POS); +} + +/** + * @tc.name: EasingEquationCircEaseOut_001 + * @tc.desc: Verify CircEaseOut and GetHeight function. + * @tc.type: FUNC + * @tc.require: AR000DSMQM + */ +HWTEST_F(EasingEquationTest, EasingEquationCircEaseOut_001, TestSize.Level1) +{ + uint16_t i = 0; + EXPECT_EQ(EasingEquation::CircEaseOut(START_POS, END_POS, i++, DURATION_TIME), 0); + EXPECT_EQ(EasingEquation::CircEaseOut(START_POS, END_POS, i++, DURATION_TIME), 66); // 66:the value for 1th s; + EXPECT_EQ(EasingEquation::CircEaseOut(START_POS, END_POS, i++, DURATION_TIME), 86); // 86:the value for 2th s; + EXPECT_EQ(EasingEquation::CircEaseOut(START_POS, END_POS, i++, DURATION_TIME), 96); // 96:the value for 3th s; + EXPECT_EQ(EasingEquation::CircEaseOut(START_POS, END_POS, i++, DURATION_TIME), END_POS); +} + +/** + * @tc.name: EasingEquationCircEaseInOut_001 + * @tc.desc: Verify CircEaseInOut and GetHeight function. + * @tc.type: FUNC + * @tc.require: AR000DSMQM + */ +HWTEST_F(EasingEquationTest, EasingEquationCircEaseInOut_001, TestSize.Level1) +{ + uint16_t i = 0; + EXPECT_EQ(EasingEquation::CircEaseInOut(START_POS, END_POS, i++, DURATION_TIME), 0); + EXPECT_EQ(EasingEquation::CircEaseInOut(START_POS, END_POS, i++, DURATION_TIME), 6); // 6:the value for 1th s; + EXPECT_EQ(EasingEquation::CircEaseInOut(START_POS, END_POS, i++, DURATION_TIME), 50); // 50:the value for 2th s; + EXPECT_EQ(EasingEquation::CircEaseInOut(START_POS, END_POS, i++, DURATION_TIME), 93); // 93:the value for 3th s; + EXPECT_EQ(EasingEquation::CircEaseInOut(START_POS, END_POS, i++, DURATION_TIME), END_POS); +} + +/** + * @tc.name: EasingEquationCubicEaseIn_001 + * @tc.desc: Verify CubicEaseIn and GetHeight function. + * @tc.type: FUNC + * @tc.require: AR000DSMQM + */ +HWTEST_F(EasingEquationTest, EasingEquationCubicEaseIn_001, TestSize.Level1) +{ + uint16_t i = 0; + EXPECT_EQ(EasingEquation::CubicEaseIn(START_POS, END_POS, i++, DURATION_TIME), 0); + EXPECT_EQ(EasingEquation::CubicEaseIn(START_POS, END_POS, i++, DURATION_TIME), 1); // 1:the value for 1th s; + EXPECT_EQ(EasingEquation::CubicEaseIn(START_POS, END_POS, i++, DURATION_TIME), 12); // 12:the value for 2th s; + EXPECT_EQ(EasingEquation::CubicEaseIn(START_POS, END_POS, i++, DURATION_TIME), 42); // 42:the value for 3th s; + EXPECT_EQ(EasingEquation::CubicEaseIn(START_POS, END_POS, i++, DURATION_TIME), END_POS); +} + +/** + * @tc.name: EasingEquationCubicEaseOut_001 + * @tc.desc: Verify CubicEaseOut and GetHeight function. + * @tc.type: FUNC + * @tc.require: AR000DSMQM + */ +HWTEST_F(EasingEquationTest, EasingEquationCubicEaseOut_001, TestSize.Level1) +{ + uint16_t i = 0; + EXPECT_EQ(EasingEquation::CubicEaseOut(START_POS, END_POS, i++, DURATION_TIME), 0); + EXPECT_EQ(EasingEquation::CubicEaseOut(START_POS, END_POS, i++, DURATION_TIME), 57); // 57:the value for 1th s; + EXPECT_EQ(EasingEquation::CubicEaseOut(START_POS, END_POS, i++, DURATION_TIME), 87); // 87:the value for 2th s; + EXPECT_EQ(EasingEquation::CubicEaseOut(START_POS, END_POS, i++, DURATION_TIME), 98); // 98:the value for 3th s; + EXPECT_EQ(EasingEquation::CubicEaseOut(START_POS, END_POS, i++, DURATION_TIME), END_POS); +} + +/** + * @tc.name: EasingEquationCubicEaseInOut_001 + * @tc.desc: Verify CubicEaseInOut and GetHeight function. + * @tc.type: FUNC + * @tc.require: AR000DSMQM + */ +HWTEST_F(EasingEquationTest, EasingEquationCubicEaseInOut_001, TestSize.Level1) +{ + uint16_t i = 0; + EXPECT_EQ(EasingEquation::CubicEaseInOut(START_POS, END_POS, i++, DURATION_TIME), 0); + EXPECT_EQ(EasingEquation::CubicEaseInOut(START_POS, END_POS, i++, DURATION_TIME), 6); // 6:the value for 1th s; + EXPECT_EQ(EasingEquation::CubicEaseInOut(START_POS, END_POS, i++, DURATION_TIME), 50); // 50:the value for 2th s; + EXPECT_EQ(EasingEquation::CubicEaseInOut(START_POS, END_POS, i++, DURATION_TIME), 93); // 93:the value for 3th s; + EXPECT_EQ(EasingEquation::CubicEaseInOut(START_POS, END_POS, i++, DURATION_TIME), END_POS); +} + +/** + * @tc.name: EasingEquationLinearEaseNone_001 + * @tc.desc: Verify LinearEaseNone and GetHeight function. + * @tc.type: FUNC + * @tc.require: AR000DSMQM + */ +HWTEST_F(EasingEquationTest, EasingEquationLinearEaseNone_001, TestSize.Level1) +{ + uint16_t i = 0; + EXPECT_EQ(EasingEquation::LinearEaseNone(START_POS, END_POS, i++, DURATION_TIME), 0); + EXPECT_EQ(EasingEquation::LinearEaseNone(START_POS, END_POS, i++, DURATION_TIME), 25); // 25:the value for 1th s; + EXPECT_EQ(EasingEquation::LinearEaseNone(START_POS, END_POS, i++, DURATION_TIME), 50); // 50:the value for 2th s; + EXPECT_EQ(EasingEquation::LinearEaseNone(START_POS, END_POS, i++, DURATION_TIME), 75); // 75:the value for 3th s; + EXPECT_EQ(EasingEquation::LinearEaseNone(START_POS, END_POS, i++, DURATION_TIME), END_POS); +} + +/** + * @tc.name: EasingEquationQuadEaseIn_001 + * @tc.desc: Verify QuadEaseIn and GetHeight function. + * @tc.type: FUNC + * @tc.require: AR000DSMQM + */ +HWTEST_F(EasingEquationTest, EasingEquationQuadEaseIn_001, TestSize.Level1) +{ + uint16_t i = 0; + EXPECT_EQ(EasingEquation::QuadEaseIn(START_POS, END_POS, i++, DURATION_TIME), 0); + EXPECT_EQ(EasingEquation::QuadEaseIn(START_POS, END_POS, i++, DURATION_TIME), 6); // 6:the value for 1th s; + EXPECT_EQ(EasingEquation::QuadEaseIn(START_POS, END_POS, i++, DURATION_TIME), 25); // 25:the value for 2th s; + EXPECT_EQ(EasingEquation::QuadEaseIn(START_POS, END_POS, i++, DURATION_TIME), 56); // 56:the value for 3th s; + EXPECT_EQ(EasingEquation::QuadEaseIn(START_POS, END_POS, i++, DURATION_TIME), END_POS); +} + +/** + * @tc.name: EasingEquationQuadEaseOut_001 + * @tc.desc: Verify QuadEaseOut and GetHeight function. + * @tc.type: FUNC + * @tc.require: AR000DSMQM + */ +HWTEST_F(EasingEquationTest, EasingEquationQuadEaseOut_001, TestSize.Level1) +{ + uint16_t i = 0; + EXPECT_EQ(EasingEquation::QuadEaseOut(START_POS, END_POS, i++, DURATION_TIME), 0); + EXPECT_EQ(EasingEquation::QuadEaseOut(START_POS, END_POS, i++, DURATION_TIME), 43); // 43:the value for 1th s; + EXPECT_EQ(EasingEquation::QuadEaseOut(START_POS, END_POS, i++, DURATION_TIME), 75); // 75:the value for 2th s; + EXPECT_EQ(EasingEquation::QuadEaseOut(START_POS, END_POS, i++, DURATION_TIME), 93); // 93:the value for 3th s; + EXPECT_EQ(EasingEquation::QuadEaseOut(START_POS, END_POS, i++, DURATION_TIME), END_POS); +} + +/** + * @tc.name: EasingEquationQuadEaseInOut_001 + * @tc.desc: Verify QuadEaseInOut and GetHeight function. + * @tc.type: FUNC + * @tc.require: AR000DSMQM + */ +HWTEST_F(EasingEquationTest, EasingEquationQuadEaseInOut_001, TestSize.Level1) +{ + uint16_t i = 0; + EXPECT_EQ(EasingEquation::QuadEaseInOut(START_POS, END_POS, i++, DURATION_TIME), 0); + EXPECT_EQ(EasingEquation::QuadEaseInOut(START_POS, END_POS, i++, DURATION_TIME), 12); // 12:the value for 1th s; + EXPECT_EQ(EasingEquation::QuadEaseInOut(START_POS, END_POS, i++, DURATION_TIME), 50); // 50:the value for 2th s; + EXPECT_EQ(EasingEquation::QuadEaseInOut(START_POS, END_POS, i++, DURATION_TIME), 87); // 87:the value for 3th s; + EXPECT_EQ(EasingEquation::QuadEaseInOut(START_POS, END_POS, i++, DURATION_TIME), END_POS); +} + +/** + * @tc.name: EasingEquationQuintEaseIn_001 + * @tc.desc: Verify QuintEaseIn and GetHeight function. + * @tc.type: FUNC + * @tc.require: AR000DSMQM + */ +HWTEST_F(EasingEquationTest, EasingEquationQuintEaseIn_001, TestSize.Level1) +{ + uint16_t i = 0; + EXPECT_EQ(EasingEquation::QuintEaseIn(START_POS, END_POS, i++, DURATION_TIME), 0); + EXPECT_EQ(EasingEquation::QuintEaseIn(START_POS, END_POS, i++, DURATION_TIME), 0); // 0:the value for 1th s; + EXPECT_EQ(EasingEquation::QuintEaseIn(START_POS, END_POS, i++, DURATION_TIME), 3); // 3:the value for 2th s; + EXPECT_EQ(EasingEquation::QuintEaseIn(START_POS, END_POS, i++, DURATION_TIME), 23); // 23:the value for 3th s; + EXPECT_EQ(EasingEquation::QuintEaseIn(START_POS, END_POS, i++, DURATION_TIME), END_POS); +} + +/** + * @tc.name: EasingEquationQuintEaseOut_001 + * @tc.desc: Verify QuintEaseOut and GetHeight function. + * @tc.type: FUNC + * @tc.require: AR000DSMQM + */ +HWTEST_F(EasingEquationTest, EasingEquationQuintEaseOut_001, TestSize.Level1) +{ + uint16_t i = 0; + EXPECT_EQ(EasingEquation::QuintEaseOut(START_POS, END_POS, i++, DURATION_TIME), 0); + EXPECT_EQ(EasingEquation::QuintEaseOut(START_POS, END_POS, i++, DURATION_TIME), 76); // 76:the value for 1th s; + EXPECT_EQ(EasingEquation::QuintEaseOut(START_POS, END_POS, i++, DURATION_TIME), 96); // 96:the value for 2th s; + EXPECT_EQ(EasingEquation::QuintEaseOut(START_POS, END_POS, i++, DURATION_TIME), 99); // 99:the value for 3th s; + EXPECT_EQ(EasingEquation::QuintEaseOut(START_POS, END_POS, i++, DURATION_TIME), END_POS); +} + +/** + * @tc.name: EasingEquationQuintEaseInOut_001 + * @tc.desc: Verify QuintEaseInOut and GetHeight function. + * @tc.type: FUNC + * @tc.require: AR000DSMQM + */ +HWTEST_F(EasingEquationTest, EasingEquationQuintEaseInOut_001, TestSize.Level1) +{ + uint16_t i = 0; + EXPECT_EQ(EasingEquation::QuintEaseInOut(START_POS, END_POS, i++, DURATION_TIME), 0); + EXPECT_EQ(EasingEquation::QuintEaseInOut(START_POS, END_POS, i++, DURATION_TIME), 1); // 1:the value for 1th s; + EXPECT_EQ(EasingEquation::QuintEaseInOut(START_POS, END_POS, i++, DURATION_TIME), 50); // 50:the value for 2th s; + EXPECT_EQ(EasingEquation::QuintEaseInOut(START_POS, END_POS, i++, DURATION_TIME), 98); // 87:the value for 3th s; + EXPECT_EQ(EasingEquation::QuintEaseInOut(START_POS, END_POS, i++, DURATION_TIME), END_POS); +} + +/** + * @tc.name: EasingEquationSineEaseIn_001 + * @tc.desc: Verify SineEaseIn and GetHeight function. + * @tc.type: FUNC + * @tc.require: AR000DSMQM + */ +HWTEST_F(EasingEquationTest, EasingEquationSineEaseIn_001, TestSize.Level1) +{ + uint16_t i = 0; + EXPECT_EQ(EasingEquation::SineEaseIn(START_POS, END_POS, i++, DURATION_TIME), 0); + EXPECT_EQ(EasingEquation::SineEaseIn(START_POS, END_POS, i++, DURATION_TIME), 7); // 7:the value for 1th s; + EXPECT_EQ(EasingEquation::SineEaseIn(START_POS, END_POS, i++, DURATION_TIME), 29); // 29:the value for 2th s; + EXPECT_EQ(EasingEquation::SineEaseIn(START_POS, END_POS, i++, DURATION_TIME), 60); // 60:the value for 3th s; + EXPECT_EQ(EasingEquation::SineEaseIn(START_POS, END_POS, i++, DURATION_TIME), END_POS); +} + +/** + * @tc.name: EasingEquationSineEaseOut_001 + * @tc.desc: Verify SineEaseOut and GetHeight function. + * @tc.type: FUNC + * @tc.require: AR000DSMQM + */ +HWTEST_F(EasingEquationTest, EasingEquationSineEaseOut_001, TestSize.Level1) +{ + uint16_t i = 0; + EXPECT_EQ(EasingEquation::SineEaseOut(START_POS, END_POS, i++, DURATION_TIME), 0); + EXPECT_EQ(EasingEquation::SineEaseOut(START_POS, END_POS, i++, DURATION_TIME), 37); // 37:the value for 1th s; + EXPECT_EQ(EasingEquation::SineEaseOut(START_POS, END_POS, i++, DURATION_TIME), 70); // 70:the value for 2th s; + EXPECT_EQ(EasingEquation::SineEaseOut(START_POS, END_POS, i++, DURATION_TIME), 92); // 92:the value for 3th s; + EXPECT_EQ(EasingEquation::SineEaseOut(START_POS, END_POS, i++, DURATION_TIME), END_POS); +} + +/** + * @tc.name: EasingEquationSineEaseInOut_001 + * @tc.desc: Verify SineEaseInOut and GetHeight function. + * @tc.type: FUNC + * @tc.require: AR000DSMQM + */ +HWTEST_F(EasingEquationTest, EasingEquationSineEaseInOut_001, TestSize.Level1) +{ + uint16_t i = 0; + EXPECT_EQ(EasingEquation::SineEaseInOut(START_POS, END_POS, i++, DURATION_TIME), 0); + EXPECT_EQ(EasingEquation::SineEaseInOut(START_POS, END_POS, i++, DURATION_TIME), 14); // 14:the value for 1th s; + EXPECT_EQ(EasingEquation::SineEaseInOut(START_POS, END_POS, i++, DURATION_TIME), 50); // 50:the value for 2th s; + EXPECT_EQ(EasingEquation::SineEaseInOut(START_POS, END_POS, i++, DURATION_TIME), 85); // 85:the value for 3th s; + EXPECT_EQ(EasingEquation::SineEaseInOut(START_POS, END_POS, i++, DURATION_TIME), END_POS); +} +} // namespace OHOS diff --git a/test/unittest/animator/interpolation_unit_test.cpp b/test/unittest/animator/interpolation_unit_test.cpp new file mode 100755 index 0000000..a8d5a59 --- /dev/null +++ b/test/unittest/animator/interpolation_unit_test.cpp @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "animator/interpolation.h" + +#include +#include + +using namespace testing::ext; +namespace OHOS { +namespace { + constexpr int16_t U1 = 512; + constexpr int16_t U2 = 256; + constexpr int16_t U3 = 128; + constexpr int16_t U4 = 512; +} +class InterpolationTest : public testing::Test { +public: + static void SetUpTestCase(void) {} + static void TearDownTestCase(void) {} +}; + +/** + * @tc.name: InterpolationGetBezierInterpolation_001 + * @tc.desc: Verify GetBezierInterpolation function, equal. + * @tc.type: FUNC + * @tc.require: AR000DSMQM + */ +HWTEST_F(InterpolationTest, InterpolationGetBezierInterpolation_001, TestSize.Level1) +{ + int16_t ret = Interpolation::GetBezierInterpolation(200, U1, U2, U3, U4); // 200:current change rate; + EXPECT_EQ(ret, 379); // 379:current change rate; + ret = Interpolation::GetBezierInterpolation(500, U1, U2, U3, U4); // 500:current change rate; + EXPECT_EQ(ret, 273); // 273:current change rate; + ret = Interpolation::GetBezierInterpolation(700, U1, U2, U3, U4); // 700:current change rate; + EXPECT_EQ(ret, 289); // 289:current change rate; + ret = Interpolation::GetBezierInterpolation(900, U1, U2, U3, U4); // 900:current change rate; + EXPECT_EQ(ret, 394); // 394:current change rate; +} +} // namespace OHOS \ No newline at end of file diff --git a/test/unittest/common/hardware_acceleration_unit_test.cpp b/test/unittest/common/hardware_acceleration_unit_test.cpp new file mode 100644 index 0000000..9c39f1a --- /dev/null +++ b/test/unittest/common/hardware_acceleration_unit_test.cpp @@ -0,0 +1,291 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "common/graphic_startup.h" +#include "common/task_manager.h" +#include "components/root_view.h" +#include "components/ui_image_view.h" +#include "components/ui_label.h" +#include "components/ui_texture_mapper.h" +#include "components/ui_view_group.h" +#include "dock/screen_device.h" +#include "dock/screen_device_proxy.h" +#include "style.h" +#include "test_resource_config.h" +#include "window/window.h" + +#include +#include + +using namespace testing::ext; +namespace OHOS { +class TestDevice : public ScreenDevice { +public: + TestDevice() {} + virtual ~TestDevice() {} + + bool HardwareFill(const Rect& fillArea, + uint32_t color, + OpacityType opa, + uint8_t* dst, + uint32_t dstStride, + ColorMode dstColorMode) override + { + fillIn_ = true; + return false; + } + + bool HardwareBlend(const uint8_t* src, + const Rect& srcRect, + uint32_t srcStride, + uint32_t srcLineNumber, + ColorMode srcColorMode, + uint32_t color, + OpacityType opa, + uint8_t* dst, + uint32_t dstStride, + ColorMode dstColorMode, + uint32_t x, + uint32_t y) override + { + blendIn_ = true; + return false; + } + + bool HardwareTransform(const uint8_t* src, + ColorMode srcColorMode, + const Rect& srcRect, + const Matrix3& transformMatrix, + OpacityType opa, + uint32_t color, + const Rect& mask, + uint8_t* dst, + uint32_t dstStride, + ColorMode dstColorMode, + const TransformOption& option) override + { + transformIn_ = true; + return false; + } + + bool fillIn_ = false; + bool blendIn_ = false; + bool transformIn_ = false; +}; + +static TestDevice* g_testDevice = nullptr; + +class HardwareAccelerationTest : public testing::Test { +public: + static void SetUpTestCase(void) + { + GraphicStartUp::Init(); + g_testDevice = new TestDevice; + ScreenDeviceProxy::GetInstance()->SetDevice(g_testDevice); + } + static void TearDownTestCase(void) + { + delete g_testDevice; + g_testDevice = nullptr; + ScreenDeviceProxy::GetInstance()->SetDevice(nullptr); + } + void SetUp() + { + g_testDevice->fillIn_ = false; + g_testDevice->blendIn_ = false; + g_testDevice->transformIn_ = false; + } + void TearDown() {} + + static void CreateDefaultWindow(RootView* rootView, int x, int y) + { + WindowConfig config = {}; + config.rect = rootView->GetRect(); + config.rect.SetPosition(x, y); + Window* window = Window::CreateWindow(config); + if (window != nullptr) { + window->BindRootView(rootView); + } + } +}; + +/** + * @tc.name: HardwareFill_001 + * @tc.desc: Verify HardwareFill function, equal. + * Need set ENABLE_HARDWARE_ACCELERATION to 1. + * @tc.type: FUNC + * @tc.require: SR000ERCR6 + */ +#if ENABLE_HARDWARE_ACCELERATION +HWTEST_F(HardwareAccelerationTest, HardwareFill_001, TestSize.Level0) +{ + RootView* rootView = RootView::GetInstance(); + rootView->SetWidth(600); // 600: width + rootView->SetHeight(300); // 300: height + rootView->SetPosition(0, 0); + rootView->SetStyle(STYLE_BACKGROUND_COLOR, Color::Olive().full); + rootView->Invalidate(); + + HardwareAccelerationTest::CreateDefaultWindow(rootView, 0, 0); + + TaskManager::GetInstance()->TaskHandler(); + EXPECT_EQ(g_testDevice->fillIn_, true); + Window::DestoryWindow(rootView->GetBoundWindow()); +} +#endif + +/** + * @tc.name: HardwareBlend_001 + * @tc.desc: Verify HardwareBlend function, equal. + * Need set ENABLE_HARDWARE_ACCELERATION to 1. + * @tc.type: FUNC + * @tc.require: AR000EVI3I + */ +#if ENABLE_HARDWARE_ACCELERATION +HWTEST_F(HardwareAccelerationTest, HardwareBlend_001, TestSize.Level0) +{ + RootView* rootView = RootView::GetInstance(); + rootView->SetWidth(600); // 600: width + rootView->SetHeight(300); // 300: height + rootView->SetPosition(0, 0); + rootView->SetStyle(STYLE_BACKGROUND_COLOR, Color::Olive().full); + + UIImageView* imageView = new UIImageView; + imageView->SetPosition(200, 50, 200, 200); // 200: x; 50: y; 200: width; 200: height + imageView->SetSrc(RED_IMAGE_PATH); + + rootView->Add(imageView); + rootView->Invalidate(); + + HardwareAccelerationTest::CreateDefaultWindow(rootView, 0, 0); + + TaskManager::GetInstance()->TaskHandler(); + EXPECT_EQ(g_testDevice->blendIn_, true); + Window::DestoryWindow(rootView->GetBoundWindow()); +} +#endif + +/** + * @tc.name: HardwareBlend_002 + * @tc.desc: Verify HardwareBlend function for text, equal. + * Need set ENABLE_HARDWARE_ACCELERATION and ENABLE_HARDWARE_ACCELERATION_FOR_TEXT to 1. + * @tc.type: FUNC + * @tc.require: AR000EVI3I + */ +#if ENABLE_HARDWARE_ACCELERATION && ENABLE_HARDWARE_ACCELERATION_FOR_TEXT +HWTEST_F(HardwareAccelerationTest, HardwareBlend_002, TestSize.Level0) +{ + RootView* rootView = RootView::GetInstance(); + rootView->SetWidth(600); // 600: width + rootView->SetHeight(300); // 300: height + rootView->SetPosition(0, 0); + rootView->SetStyle(STYLE_BACKGROUND_COLOR, Color::Olive().full); + + UILabel* label = new UILabel(); + // 288: x-coordinate; 48: y-coordinate + label->SetPosition(0, 0, 288, 48); + label->SetText("HardwareBlend_002 测试"); + label->SetFont(DEFAULT_VECTOR_FONT_FILENAME, 18); // 18 : font size + + rootView->Add(label); + rootView->Invalidate(); + + HardwareAccelerationTest::CreateDefaultWindow(rootView, 0, 0); + + TaskManager::GetInstance()->TaskHandler(); + EXPECT_EQ(g_testDevice->blendIn_, true); + Window::DestoryWindow(rootView->GetBoundWindow()); +} +#endif + +/** + * @tc.name: HardwareTransform_001 + * @tc.desc: Verify HardwareTransform function, equal. + * Need set ENABLE_HARDWARE_ACCELERATION to 1. + * @tc.type: FUNC + * @tc.require: AR000EVI3I + */ +#if ENABLE_HARDWARE_ACCELERATION +HWTEST_F(HardwareAccelerationTest, HardwareTransform_001, TestSize.Level0) +{ + RootView* rootView = RootView::GetInstance(); + rootView->SetWidth(600); // 600: width + rootView->SetHeight(300); // 300: height + rootView->SetPosition(0, 0); + rootView->SetStyle(STYLE_BACKGROUND_COLOR, Color::Olive().full); + + UIImageView* imageView = new UIImageView; + imageView->SetPosition(200, 50, 200, 200); // 200: x; 50: y; 200: width; 200: height + imageView->SetSrc(RED_IMAGE_PATH); + Rect viewRect = imageView->GetOrigRect(); + TransformMap transMap(viewRect); + Vector2 pivot_(58, 58); // 58:x value 58:y value + transMap.Rotate(90, pivot_); // 90:degree + transMap.Scale(Vector2(1.5, 1.5), pivot_); // 1.5:x scale 1.5:y scale + imageView->SetTransformMap(transMap); + + rootView->Add(imageView); + rootView->Invalidate(); + + HardwareAccelerationTest::CreateDefaultWindow(rootView, 0, 0); + + TaskManager::GetInstance()->TaskHandler(); + EXPECT_EQ(g_testDevice->transformIn_, true); + Window::DestoryWindow(rootView->GetBoundWindow()); +} +#endif + +/** + * @tc.name: HardwareTransform_002 + * @tc.desc: Verify HardwareTransform function in abnormal scene, equal. + * Need set ENABLE_HARDWARE_ACCELERATION to 1. + * @tc.type: FUNC + * @tc.require: AR000EVI3I + */ +#if ENABLE_HARDWARE_ACCELERATION +HWTEST_F(HardwareAccelerationTest, HardwareTransform_002, TestSize.Level0) +{ + // set device to null + ScreenDeviceProxy::GetInstance()->SetDevice(nullptr); + + RootView* rootView = RootView::GetInstance(); + rootView->SetWidth(600); // 600: width + rootView->SetHeight(300); // 300: height + rootView->SetPosition(0, 0); + rootView->SetStyle(STYLE_BACKGROUND_COLOR, Color::Olive().full); + + UIImageView* imageView = new UIImageView; + imageView->SetPosition(200, 50, 200, 200); // 200: x; 50: y; 200: width; 200: height + imageView->SetSrc(RED_IMAGE_PATH); + Rect viewRect = imageView->GetOrigRect(); + TransformMap transMap(viewRect); + Vector2 pivot_(58, 58); // 58:x value 58:y value + transMap.Rotate(90, pivot_); // 90:degree + transMap.Scale(Vector2(1.5, 1.5), pivot_); // 1.5:x scale 1.5:y scale + imageView->SetTransformMap(transMap); + + rootView->Add(imageView); + rootView->Invalidate(); + + HardwareAccelerationTest::CreateDefaultWindow(rootView, 0, 0); + + TaskManager::GetInstance()->TaskHandler(); + EXPECT_EQ(g_testDevice->fillIn_, false); + EXPECT_EQ(g_testDevice->blendIn_, false); + EXPECT_EQ(g_testDevice->transformIn_, false); + Window::DestoryWindow(rootView->GetBoundWindow()); +} +#endif +} // namespace OHOS \ No newline at end of file diff --git a/test/unittest/common/screen_unit_test.cpp b/test/unittest/common/screen_unit_test.cpp new file mode 100755 index 0000000..c451b59 --- /dev/null +++ b/test/unittest/common/screen_unit_test.cpp @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "common/screen.h" + +#include +#include + +using namespace testing::ext; +namespace OHOS { +class ScreenTest : public testing::Test { +public: + static void SetUpTestCase(void) {} + static void TearDownTestCase(void) {} +}; + +/** + * @tc.name: ScreenGetWidth_001 + * @tc.desc: Verify GetWidth function, equal. + * @tc.type: FUNC + * @tc.require: AR000EEMQ9 + */ +HWTEST_F(ScreenTest, ScreenGetWidth_001, TestSize.Level0) +{ + EXPECT_EQ(Screen::GetInstance().GetWidth(), HORIZONTAL_RESOLUTION); +} + +/** + * @tc.name: ScreenGetHeight_001 + * @tc.desc: Verify GetHeight function, equal. + * @tc.type: FUNC + * @tc.require: AR000EEMQ9 + */ +HWTEST_F(ScreenTest, ScreenGetHeight_001, TestSize.Level0) +{ + EXPECT_EQ(Screen::GetInstance().GetHeight(), VERTICAL_RESOLUTION); +} +} // namespace OHOS \ No newline at end of file diff --git a/test/unittest/common/text_unit_test.cpp b/test/unittest/common/text_unit_test.cpp new file mode 100755 index 0000000..cafb789 --- /dev/null +++ b/test/unittest/common/text_unit_test.cpp @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "common/text.h" + +#include +#include + +using namespace testing::ext; +namespace OHOS { +class TextTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + static Text* text_; +}; + +Text* TextTest::text_ = nullptr; + +void TextTest::SetUpTestCase(void) +{ + if (text_ == nullptr) { + text_ = new Text(); + } +} + +void TextTest::TearDownTestCase(void) +{ + if (text_ != nullptr) { + delete text_; + text_ = nullptr; + } +} + +/** + * @tc.name: TextSetText_001 + * @tc.desc: Verify SetText function, equal. + * @tc.type: FUNC + * @tc.require: AR000DSMQ1 + */ +HWTEST_F(TextTest, TextSetText_001, TestSize.Level0) +{ + if (text_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + const char* text = "unit test text"; + text_->SetText(text); + EXPECT_EQ(strcmp(text_->GetText(), text), 0); +} + +/** + * @tc.name: TextSetDirect_001 + * @tc.desc: Verify SetDirect function, equal. + * @tc.type: FUNC + * @tc.require: AR000DSMQ1 + */ +HWTEST_F(TextTest, TextSetDirect_001, TestSize.Level0) +{ + if (text_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + UITextLanguageDirect direct = UITextLanguageDirect::TEXT_DIRECT_LTR; + text_->SetDirect(direct); + EXPECT_EQ(text_->GetDirect(), direct); + direct = UITextLanguageDirect::TEXT_DIRECT_RTL; + text_->SetDirect(direct); + EXPECT_EQ(text_->GetDirect(), direct); +} + +/** + * @tc.name: TextSetAlign_001 + * @tc.desc: Verify SetAlign function, equal. + * @tc.type: FUNC + * @tc.require: AR000DSMQ1 + */ +HWTEST_F(TextTest, TextSetAlign_001, TestSize.Level0) +{ + if (text_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + text_->SetAlign(TEXT_ALIGNMENT_LEFT, TEXT_ALIGNMENT_TOP); + EXPECT_EQ(text_->IsNeedRefresh(), true); + EXPECT_EQ(text_->GetHorAlign(), TEXT_ALIGNMENT_LEFT); + EXPECT_EQ(text_->GetVerAlign(), TEXT_ALIGNMENT_TOP); +} + +/** + * @tc.name: TextSetExpand_001 + * @tc.desc: Verify SetExpand function, equal. + * @tc.type: FUNC + * @tc.require: AR000DSMQ1 + */ +HWTEST_F(TextTest, TextSetExpand_001, TestSize.Level0) +{ + if (text_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + EXPECT_EQ(text_->IsExpandWidth(), false); + text_->SetExpandWidth(true); + EXPECT_EQ(text_->IsExpandWidth(), true); + + EXPECT_EQ(text_->IsExpandHeight(), false); + text_->SetExpandHeight(true); + EXPECT_EQ(text_->IsExpandHeight(), true); +} +} // namespace OHOS \ No newline at end of file diff --git a/test/unittest/components/ui_abstract_progress_unit_test.cpp b/test/unittest/components/ui_abstract_progress_unit_test.cpp new file mode 100755 index 0000000..d1ef2da --- /dev/null +++ b/test/unittest/components/ui_abstract_progress_unit_test.cpp @@ -0,0 +1,209 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "components/ui_abstract_progress.h" + +#include +#include + +using namespace testing::ext; +namespace OHOS { +namespace { + const int16_t MAX_VALUE = 80; + const int16_t MEDIAN_VALUE = 50; + const int16_t MIN_VALUE = 20; +} +class UIAbsatrctProgressTest : public testing::Test { +public: + UIAbsatrctProgressTest() : abstractProgress_(nullptr) {} + virtual ~UIAbsatrctProgressTest() {} + static void SetUpTestCase(); + static void TearDownTestCase(); + void SetUp(); + void TearDown(); + UIAbstractProgress* abstractProgress_; +}; + +void UIAbsatrctProgressTest::SetUpTestCase() +{ +} + +void UIAbsatrctProgressTest::TearDownTestCase() +{ +} + +void UIAbsatrctProgressTest::SetUp() +{ + if (abstractProgress_ == nullptr) { + abstractProgress_ = new UIAbstractProgress(); + } +} + +void UIAbsatrctProgressTest::TearDown() +{ + if (abstractProgress_ != nullptr) { + delete abstractProgress_; + abstractProgress_ = nullptr; + } +} +/** + * @tc.name: UIAbsatrctProgressGetViewType_001 + * @tc.desc: Verify GetViewType function, equal. + * @tc.type: FUNC + * @tc.require: AR000DSMQG + */ +HWTEST_F(UIAbsatrctProgressTest, UIAbsatrctProgressGetViewType_001, TestSize.Level0) +{ + if (abstractProgress_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + EXPECT_EQ(abstractProgress_->GetViewType(), UI_ABSTRACT_PROGRESS); +} + +/** + * @tc.name: UIAbsatrctProgressSetValue_001 + * @tc.desc: Verify SetValue function, equal. + * @tc.type: FUNC + * @tc.require: AR000DSMQG + */ +HWTEST_F(UIAbsatrctProgressTest, UIAbsatrctProgressSetValue_001, TestSize.Level0) +{ + if (abstractProgress_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + abstractProgress_->SetRange(MAX_VALUE, MIN_VALUE); + EXPECT_EQ(abstractProgress_->GetRangeMin(), MIN_VALUE); + EXPECT_EQ(abstractProgress_->GetRangeMax(), MAX_VALUE); + + abstractProgress_->SetValue(MEDIAN_VALUE); + EXPECT_EQ(abstractProgress_->GetValue(), MEDIAN_VALUE); + + abstractProgress_->SetValue(MAX_VALUE + 1); + EXPECT_EQ(abstractProgress_->GetValue(), MAX_VALUE); + + abstractProgress_->SetValue(MIN_VALUE - 1); + EXPECT_EQ(abstractProgress_->GetValue(), MIN_VALUE); +} + +/** + * @tc.name: UIAbsatrctProgressSetValue_002 + * @tc.desc: Verify SetValue function, equal. + * @tc.type: FUNC + * @tc.require: AR000DSMQG + */ +HWTEST_F(UIAbsatrctProgressTest, UIAbsatrctProgressSetValue_002, TestSize.Level0) +{ + if (abstractProgress_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + abstractProgress_->SetRange(MAX_VALUE, MIN_VALUE); + EXPECT_EQ(abstractProgress_->GetRangeMin(), MIN_VALUE); + EXPECT_EQ(abstractProgress_->GetRangeMax(), MAX_VALUE); + + abstractProgress_->SetRange(MIN_VALUE, MAX_VALUE); + EXPECT_EQ(abstractProgress_->GetRangeMin(), MIN_VALUE); + EXPECT_EQ(abstractProgress_->GetRangeMax(), MAX_VALUE); +} + +/** + * @tc.name: UIAbsatrctProgressSetStep_001 + * @tc.desc: Verify SetStep function, equal. + * @tc.type: FUNC + * @tc.require: AR000DSMQG + */ +HWTEST_F(UIAbsatrctProgressTest, UIAbsatrctProgressSetStep_001, TestSize.Level0) +{ + if (abstractProgress_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + abstractProgress_->SetStep(MEDIAN_VALUE); + EXPECT_EQ(abstractProgress_->GetStep(), MEDIAN_VALUE); +} + +/** + * @tc.name: UIAbsatrctProgressSetBackgroundStyle_001 + * @tc.desc: Verify SetBackgroundStyle function, equal. + * @tc.type: FUNC + * @tc.require: AR000DSMQG + */ +HWTEST_F(UIAbsatrctProgressTest, UIAbsatrctProgressSetBackgroundStyle_001, TestSize.Level0) +{ + if (abstractProgress_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + Style style; + style.imageOpa_ = OPA_TRANSPARENT; + style.lineOpa_ = OPA_TRANSPARENT; + style.borderRadius_ = 1; + + abstractProgress_->SetBackgroundStyle(style); + EXPECT_EQ(abstractProgress_->GetBackgroundStyle().imageOpa_, OPA_TRANSPARENT); + EXPECT_EQ(abstractProgress_->GetBackgroundStyle().lineOpa_, OPA_TRANSPARENT); + EXPECT_EQ(abstractProgress_->GetBackgroundStyle().borderRadius_, 1); + + abstractProgress_->SetBackgroundStyle(STYLE_BACKGROUND_COLOR, Color::Silver().full); + EXPECT_EQ(abstractProgress_->GetBackgroundStyle(STYLE_BACKGROUND_COLOR), Color::Silver().full); +} + +/** + * @tc.name: UIAbsatrctProgressSetForegroundStyle_001 + * @tc.desc: Verify SetForegroundStyle function, equal. + * @tc.type: FUNC + * @tc.require: AR000DSMQG + */ +HWTEST_F(UIAbsatrctProgressTest, UIAbsatrctProgressSetForegroundStyle_001, TestSize.Level0) +{ + if (abstractProgress_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + Style style; + style.imageOpa_ = OPA_TRANSPARENT; + style.lineOpa_ = OPA_TRANSPARENT; + style.borderRadius_ = 1; + + abstractProgress_->SetForegroundStyle(style); + EXPECT_EQ(abstractProgress_->GetForegroundStyle().imageOpa_, OPA_TRANSPARENT); + EXPECT_EQ(abstractProgress_->GetForegroundStyle().lineOpa_, OPA_TRANSPARENT); + EXPECT_EQ(abstractProgress_->GetForegroundStyle().borderRadius_, 1); + + abstractProgress_->SetForegroundStyle(STYLE_BACKGROUND_COLOR, Color::White().full); + EXPECT_EQ(abstractProgress_->GetForegroundStyle(STYLE_BACKGROUND_COLOR), Color::White().full); +} + +/** + * @tc.name: UIAbsatrctProgressSetCapType_001 + * @tc.desc: Verify SetCapType function, equal. + * @tc.type: FUNC + * @tc.require: AR000DSMQG + */ +HWTEST_F(UIAbsatrctProgressTest, UIAbsatrctProgressSetCapType_001, TestSize.Level0) +{ + if (abstractProgress_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + EXPECT_EQ(abstractProgress_->GetForegroundStyle(STYLE_LINE_CAP), CapType::CAP_NONE); + EXPECT_EQ(abstractProgress_->GetBackgroundStyle(STYLE_LINE_CAP), CapType::CAP_NONE); + abstractProgress_->SetCapType(CapType::CAP_ROUND); + EXPECT_EQ(abstractProgress_->GetForegroundStyle(STYLE_LINE_CAP), CapType::CAP_ROUND); + EXPECT_EQ(abstractProgress_->GetBackgroundStyle(STYLE_LINE_CAP), CapType::CAP_ROUND); +} +} // namespace OHOS diff --git a/test/unittest/components/ui_analog_clock_unit_test.cpp b/test/unittest/components/ui_analog_clock_unit_test.cpp new file mode 100755 index 0000000..baed925 --- /dev/null +++ b/test/unittest/components/ui_analog_clock_unit_test.cpp @@ -0,0 +1,232 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "components/ui_analog_clock.h" + +#include +#include + +using namespace testing::ext; + +namespace OHOS { +namespace { + const uint8_t CURRENT_HOUR = 14; + const uint8_t CURRENT_MINUTE = 40; + const uint8_t CURRENT_SECOND = 30; + const uint8_t INIT_HOUR = 6; + const uint8_t INIT_MINUTE = 0; + const uint8_t INIT_SECOND = 0; + const uint8_t HALF_DAY_IN_HOUR = 12; +} + +class UIAnalogClockTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + static UIAnalogClock* clock_; +}; + +UIAnalogClock* UIAnalogClockTest::clock_ = nullptr; + +void UIAnalogClockTest::SetUpTestCase() +{ + if (clock_ == nullptr) { + clock_ = new UIAnalogClock(); + } +} + +void UIAnalogClockTest::TearDownTestCase() +{ + if (clock_ != nullptr) { + delete clock_; + clock_ = nullptr; + } +} + +/** + * @tc.name: UIAnalogClockGetViewType_001 + * @tc.desc: Verify GetWidth and GetHeight function. + * @tc.type: FUNC + * @tc.require: AR000DSMQ1 + */ +HWTEST_F(UIAnalogClockTest, UIAnalogClockGetViewType_001, TestSize.Level1) +{ + if (clock_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + EXPECT_EQ(clock_->GetViewType(), UI_ANALOG_CLOCK); +} + +/** + * @tc.name: UIAnalogClockSetPosition_001 + * @tc.desc: Verify GetWidth and GetHeight function. + * @tc.type: FUNC + * @tc.require: AR000DSMQ1 + */ +HWTEST_F(UIAnalogClockTest, UIAnalogClockSetPosition_001, TestSize.Level1) +{ + if (clock_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + clock_->SetPosition(0, 0); + EXPECT_EQ(clock_->GetX(), 0); + EXPECT_EQ(clock_->GetY(), 0); +} + +/** + * @tc.name: UIAnalogClockSetTime24Hour_001 + * @tc.desc: Verify SetTime24Hour function, equal. + * @tc.type: FUNC + * @tc.require: AR000EEMQA + */ +HWTEST_F(UIAnalogClockTest, UIAnalogClockSetTime24Hour_001, TestSize.Level0) +{ + if (clock_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + clock_->SetTime24Hour(CURRENT_HOUR, CURRENT_MINUTE, CURRENT_SECOND); + EXPECT_EQ(clock_->GetCurrentHour(), CURRENT_HOUR); + EXPECT_EQ(clock_->GetCurrentMinute(), CURRENT_MINUTE); + EXPECT_EQ(clock_->GetCurrentSecond(), CURRENT_SECOND); +} + +/** + * @tc.name: UIAnalogClockSetTime12Hour_001 + * @tc.desc: Verify SetTime12Hour am function, equal. + * @tc.type: FUNC + * @tc.require: AR000EEMQA + */ +HWTEST_F(UIAnalogClockTest, UIAnalogClockSetTime12Hour_001, TestSize.Level1) +{ + if (clock_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + clock_->SetTime12Hour(CURRENT_HOUR, CURRENT_MINUTE, CURRENT_SECOND, true); + EXPECT_EQ(clock_->GetCurrentHour(), CURRENT_HOUR - HALF_DAY_IN_HOUR); + EXPECT_EQ(clock_->GetCurrentMinute(), CURRENT_MINUTE); + EXPECT_EQ(clock_->GetCurrentSecond(), CURRENT_SECOND); +} + +/** + * @tc.name: UIAnalogClockSetTime12Hour_002 + * @tc.desc: Verify SetTime12Hour pm function, equal. + * @tc.type: FUNC + * @tc.require: AR000EEMQA + */ +HWTEST_F(UIAnalogClockTest, UIAnalogClockSetTime12Hour_002, TestSize.Level0) +{ + if (clock_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + clock_->SetTime12Hour(CURRENT_HOUR, CURRENT_MINUTE, CURRENT_SECOND, false); + EXPECT_EQ(clock_->GetCurrentHour(), CURRENT_HOUR); + EXPECT_EQ(clock_->GetCurrentMinute(), CURRENT_MINUTE); + EXPECT_EQ(clock_->GetCurrentSecond(), CURRENT_SECOND); +} + +/** + * @tc.name: UIAnalogClockSetHandLine_001 + * @tc.desc: Verify SetHandLine function, equal. + * @tc.type: FUNC + * @tc.require: AR000EEMQA + */ +HWTEST_F(UIAnalogClockTest, UIAnalogClockSetHandLine_001, TestSize.Level0) +{ + if (clock_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + Point position = { 214, 3 }; // { 214, 3 } : the position of the line endpoint close + Point center = { 14, 223 }; // { 14, 223 }: the rotation center of this clock hand + + clock_->SetHandLine(UIAnalogClock::HandType::SECOND_HAND, + position, center, Color::White(), 1, 223, OPA_OPAQUE); // 223:the height of this line + EXPECT_EQ(clock_->GetHandPosition(UIAnalogClock::HandType::SECOND_HAND).x, position.x); + EXPECT_EQ(clock_->GetHandPosition(UIAnalogClock::HandType::SECOND_HAND).y, position.y); + EXPECT_EQ(clock_->GetHandRotateCenter(UIAnalogClock::HandType::SECOND_HAND).x, center.x); + EXPECT_EQ(clock_->GetHandRotateCenter(UIAnalogClock::HandType::SECOND_HAND).y, center.y); +} + +/** + * @tc.name: UIAnalogClockSetInitTime24Hour_001 + * @tc.desc: Verify SetInitTime24Hour function, equal. + * @tc.type: FUNC + * @tc.require: AR000EEMQA + */ +HWTEST_F(UIAnalogClockTest, UIAnalogClockSetInitTime24Hour_001, TestSize.Level0) +{ + if (clock_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + const uint8_t hour = 9; + + clock_->SetInitTime24Hour(INIT_HOUR, INIT_MINUTE, INIT_SECOND); + EXPECT_EQ(clock_->GetCurrentHour(), INIT_HOUR); + EXPECT_EQ(clock_->GetCurrentMinute(), INIT_MINUTE); + EXPECT_EQ(clock_->GetCurrentSecond(), INIT_SECOND); + EXPECT_EQ(clock_->GetHandInitAngle(UIAnalogClock::HandType::HOUR_HAND), SEMICIRCLE_IN_DEGREE); + EXPECT_EQ(clock_->GetHandCurrentAngle(UIAnalogClock::HandType::HOUR_HAND), SEMICIRCLE_IN_DEGREE); + + clock_->SetTime24Hour(hour, 0, 0); + EXPECT_EQ(clock_->GetHandInitAngle(UIAnalogClock::HandType::HOUR_HAND), SEMICIRCLE_IN_DEGREE); + EXPECT_EQ(clock_->GetHandCurrentAngle(UIAnalogClock::HandType::HOUR_HAND), THREE_QUARTER_IN_DEGREE); +} + +/** + * @tc.name: UIAnalogClockSetInitTime12Hour_001 + * @tc.desc: Verify SetInitTime12Hour am function, equal. + * @tc.type: FUNC + * @tc.require: AR000EEMQA + */ +HWTEST_F(UIAnalogClockTest, UIAnalogClockSetInitTime12Hour_001, TestSize.Level0) +{ + if (clock_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + clock_->SetInitTime12Hour(INIT_HOUR, INIT_MINUTE, INIT_SECOND, true); + EXPECT_EQ(clock_->GetCurrentHour(), INIT_HOUR); + EXPECT_EQ(clock_->GetCurrentMinute(), INIT_MINUTE); + EXPECT_EQ(clock_->GetCurrentSecond(), INIT_SECOND); + EXPECT_EQ(clock_->GetHandInitAngle(UIAnalogClock::HandType::HOUR_HAND), SEMICIRCLE_IN_DEGREE); + EXPECT_EQ(clock_->GetHandCurrentAngle(UIAnalogClock::HandType::HOUR_HAND), SEMICIRCLE_IN_DEGREE); +} + +/** + * @tc.name: UIAnalogClockSetInitTime12Hour_002 + * @tc.desc: Verify SetInitTime12Hour pm function, equal. + * @tc.type: FUNC + * @tc.require: AR000EEMQA + */ +HWTEST_F(UIAnalogClockTest, UIAnalogClockSetInitTime12Hour_002, TestSize.Level0) +{ + if (clock_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + clock_->SetInitTime12Hour(INIT_HOUR, INIT_MINUTE, INIT_SECOND, false); + EXPECT_EQ(clock_->GetCurrentHour(), INIT_HOUR + HALF_DAY_IN_HOUR); + EXPECT_EQ(clock_->GetCurrentMinute(), INIT_MINUTE); + EXPECT_EQ(clock_->GetCurrentSecond(), INIT_SECOND); + EXPECT_EQ(clock_->GetHandInitAngle(UIAnalogClock::HandType::HOUR_HAND), SEMICIRCLE_IN_DEGREE); + EXPECT_EQ(clock_->GetHandCurrentAngle(UIAnalogClock::HandType::HOUR_HAND), SEMICIRCLE_IN_DEGREE); +} +} diff --git a/test/unittest/components/ui_arc_label_unit_test.cpp b/test/unittest/components/ui_arc_label_unit_test.cpp new file mode 100755 index 0000000..457da6d --- /dev/null +++ b/test/unittest/components/ui_arc_label_unit_test.cpp @@ -0,0 +1,217 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "components/ui_arc_label.h" + +#include +#include + +using namespace testing::ext; + +namespace OHOS { +class UIArcLabelTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + static UIArcLabel* arcLabel_; +}; +UIArcLabel* UIArcLabelTest::arcLabel_ = nullptr; + +void UIArcLabelTest::SetUpTestCase(void) +{ + if (arcLabel_ == nullptr) { + arcLabel_ = new UIArcLabel(); + } +} + +void UIArcLabelTest::TearDownTestCase(void) +{ + if (arcLabel_ != nullptr) { + delete arcLabel_; + arcLabel_ = nullptr; + } +} +/** + * @tc.name: UIArcLabelGetViewType_001 + * @tc.desc: Verify GetViewType function, equal. + * @tc.type: FUNC + * @tc.require: AR000DSMPM + */ +HWTEST_F(UIArcLabelTest, UIArcLabelGetViewType_001, TestSize.Level0) +{ + if (arcLabel_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + EXPECT_EQ(arcLabel_->GetViewType(), UI_ARC_LABEL); +} + +/** + * @tc.name: UIArcLabelGetWidth_001 + * @tc.desc: Verify GetWidth function, equal. + * @tc.type: FUNC + * @tc.require: AR000DSMPM + */ +HWTEST_F(UIArcLabelTest, UIArcLabelGetWidth_001, TestSize.Level0) +{ + if (arcLabel_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + const int16_t width = 100; + arcLabel_->SetWidth(width); + EXPECT_EQ(arcLabel_->GetWidth(), width); +} + +/** + * @tc.name: UIArcLabelGetHeight_001 + * @tc.desc: Verify GetHeight function, equal. + * @tc.type: FUNC + * @tc.require: AR000DSMPM + */ +HWTEST_F(UIArcLabelTest, UIArcLabelGetHeight_001, TestSize.Level0) +{ + if (arcLabel_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + const int16_t height = 100; + arcLabel_->SetHeight(height); + EXPECT_EQ(arcLabel_->GetHeight(), height); +} + +/** + * @tc.name: UIArcLabelSetText_001 + * @tc.desc: Verify SetText function, equal. + * @tc.type: FUNC + * @tc.require: AR000DSMPM + */ +HWTEST_F(UIArcLabelTest, UIArcLabelSetText_001, TestSize.Level0) +{ + if (arcLabel_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + const char* text = "abc"; + arcLabel_->SetText(text); + EXPECT_EQ(strcmp(arcLabel_->GetText(), text), 0); +} + +/** + * @tc.name: UIArcLabelSetAlign_001 + * @tc.desc: Verify SetAlign function, equal. + * @tc.type: FUNC + * @tc.require: AR000DSMPM + */ +HWTEST_F(UIArcLabelTest, UIArcLabelSetAlign_001, TestSize.Level0) +{ + if (arcLabel_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + UITextLanguageAlignment horizontalAlign = TEXT_ALIGNMENT_LEFT; + arcLabel_->SetAlign(horizontalAlign); + EXPECT_EQ(arcLabel_->GetHorAlign(), horizontalAlign); +} + +/** + * @tc.name: UIArcLabelSetArcTextCenter_001 + * @tc.desc: Verify SetArcTextCenter function, equal. + * @tc.type: FUNC + * @tc.require: AR000DSMPM + */ +HWTEST_F(UIArcLabelTest, UIArcLabelSetArcTextCenter_001, TestSize.Level0) +{ + if (arcLabel_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + const int16_t posX = 10; + const int16_t posY = 20; + arcLabel_->SetArcTextCenter(posX, posY); + EXPECT_EQ(arcLabel_->GetArcTextCenter().x, posX); + EXPECT_EQ(arcLabel_->GetArcTextCenter().y, posY); +} + +/** + * @tc.name: UIArcLabelSetArcTextRadius_001 + * @tc.desc: Verify SetArcTextRadius function, equal. + * @tc.type: FUNC + * @tc.require: AR000DSMPM + */ +HWTEST_F(UIArcLabelTest, UIArcLabelSetArcTextRadius_001, TestSize.Level0) +{ + if (arcLabel_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + const int16_t radius = 1; + arcLabel_->SetArcTextRadius(radius); + EXPECT_EQ(arcLabel_->GetArcTextRadius(), radius); +} + +/** + * @tc.name: UIArcLabelSetArcTextAngle_001 + * @tc.desc: Verify SetArcTextAngle function, equal. + * @tc.type: FUNC + * @tc.require: AR000DSMPM + */ +HWTEST_F(UIArcLabelTest, UIArcLabelSetArcTextAngle_001, TestSize.Level0) +{ + if (arcLabel_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + const int16_t endAngle = 10; + arcLabel_->SetArcTextAngle(0, endAngle); + EXPECT_EQ(arcLabel_->GetArcTextStartAngle(), 0); + EXPECT_EQ(arcLabel_->GetArcTextEndAngle(), endAngle); +} + +/** + * @tc.name: UIArcLabelSetArcTextOrientation_001 + * @tc.desc: Verify SetArcTextOrientation function, equal. + * @tc.type: FUNC + * @tc.require: AR000DSMPM + */ +HWTEST_F(UIArcLabelTest, UIArcLabelSetArcTextOrientation_001, TestSize.Level0) +{ + if (arcLabel_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + arcLabel_->SetArcTextOrientation(UIArcLabel::TextOrientation::INSIDE); + EXPECT_EQ(arcLabel_->GetArcTextOrientation(), + UIArcLabel::TextOrientation::INSIDE); + arcLabel_->SetArcTextOrientation(UIArcLabel::TextOrientation::OUTSIDE); + EXPECT_EQ(arcLabel_->GetArcTextOrientation(), + UIArcLabel::TextOrientation::OUTSIDE); +} + +/** + * @tc.name: UIArcLabelGetDirect_001 + * @tc.desc: Verify GetDirect function, equal. + * @tc.type: FUNC + * @tc.require: AR000DSMPM + */ +HWTEST_F(UIArcLabelTest, UIArcLabelGetDirect_001, TestSize.Level0) +{ + if (arcLabel_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + EXPECT_EQ(arcLabel_->GetDirect(), UITextLanguageDirect(0)); +} +} \ No newline at end of file diff --git a/test/unittest/components/ui_axis_unit_test.cpp b/test/unittest/components/ui_axis_unit_test.cpp new file mode 100755 index 0000000..9c65d2a --- /dev/null +++ b/test/unittest/components/ui_axis_unit_test.cpp @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "components/ui_axis.h" + +#include +#include + +using namespace testing::ext; + +namespace OHOS { +namespace { + const int16_t LARGER_VALUE = 10; + const int16_t SMALLER_VALUE = 2; +} +class UIAxisTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + static UIXAxis* axisX_; + static UIYAxis* axisY_; +}; +UIXAxis* UIAxisTest::axisX_ = nullptr; +UIYAxis* UIAxisTest::axisY_ = nullptr; + +void UIAxisTest::SetUpTestCase(void) +{ + if (axisX_ == nullptr) { + axisX_ = new UIXAxis(); + } + if (axisY_ == nullptr) { + axisY_ = new UIYAxis(); + } +} + +void UIAxisTest::TearDownTestCase(void) +{ + if (axisX_ != nullptr) { + delete axisX_; + axisX_ = nullptr; + } + if (axisY_ != nullptr) { + delete axisY_; + axisY_ = nullptr; + } +} +/** + * @tc.name: UIAxisGetViewType_001 + * @tc.desc: Verify GetViewType function, equal. + * @tc.type: FUNC + * @tc.require: AR000EEMQ8 + */ +HWTEST_F(UIAxisTest, UIAxisGetViewType_001, TestSize.Level1) +{ + if (axisX_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + EXPECT_EQ(axisX_->GetViewType(), UI_AXIS); +} + +/** + * @tc.name: UIAxisSetLineColor_001 + * @tc.desc: Verify SetLineColor function, equal. + * @tc.type: FUNC + * @tc.require: AR000EEMQ8 + */ +HWTEST_F(UIAxisTest, UIAxisSetLineColor_001, TestSize.Level0) +{ + if (axisY_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + axisY_->SetLineColor(Color::Gray()); + EXPECT_EQ(axisY_->GetStyle(STYLE_LINE_COLOR), Color::Gray().full); +} + +/** + * @tc.name: UIXAxisSetDataRange_001 + * @tc.desc: Verify SetDataRange function, equal. + * @tc.type: FUNC + * @tc.require: AR000EEMQ8 + */ +HWTEST_F(UIAxisTest, UIXAxisSetDataRange_001, TestSize.Level0) +{ + if (axisX_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + EXPECT_EQ(axisX_->SetDataRange(SMALLER_VALUE, LARGER_VALUE), true); +} + +/** + * @tc.name: UIXAxisSetDataRange_002 + * @tc.desc: Verify SetDataRange function, equal. + * @tc.type: FUNC + * @tc.require: AR000EEMQ8 + */ +HWTEST_F(UIAxisTest, UIXAxisSetDataRange_002, TestSize.Level0) +{ + if (axisX_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + EXPECT_EQ(axisX_->SetDataRange(LARGER_VALUE, SMALLER_VALUE), false); +} + +/** + * @tc.name: UIYAxisSetDataRange_001 + * @tc.desc: Verify SetDataRange function, equal. + * @tc.type: FUNC + * @tc.require: AR000EEMQ8 + */ +HWTEST_F(UIAxisTest, UIYAxisSetDataRange_001, TestSize.Level0) +{ + if (axisY_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + EXPECT_EQ(axisY_->SetDataRange(SMALLER_VALUE, LARGER_VALUE), true); +} + +/** + * @tc.name: UIYAxisSetDataRange_002 + * @tc.desc: Verify SetDataRange function, equal. + * @tc.type: FUNC + * @tc.require: AR000EEMQ8 + */ +HWTEST_F(UIAxisTest, UIYAxisSetDataRange_002, TestSize.Level0) +{ + if (axisY_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + EXPECT_EQ(axisY_->SetDataRange(LARGER_VALUE, SMALLER_VALUE), false); +} +} // namespace OHOS \ No newline at end of file diff --git a/test/unittest/components/ui_box_progress_unit_test.cpp b/test/unittest/components/ui_box_progress_unit_test.cpp new file mode 100755 index 0000000..4c18e4f --- /dev/null +++ b/test/unittest/components/ui_box_progress_unit_test.cpp @@ -0,0 +1,201 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "components/ui_box_progress.h" + +#include +#include + +using namespace testing::ext; +namespace OHOS { +namespace { + const int16_t MAX = 500; + const int16_t MIN = 100; + const int16_t WIDTH = 100; + const int16_t HEIGHT = 100; +} + +class UIBoxProgressTest : public testing::Test { +public: + UIBoxProgressTest() : boxProgress_(nullptr) {} + virtual ~UIBoxProgressTest() {} + static void SetUpTestCase(); + static void TearDownTestCase(); + void SetUp(); + void TearDown(); + UIBoxProgress* boxProgress_; +}; + +void UIBoxProgressTest::SetUpTestCase() +{ +} + +void UIBoxProgressTest::TearDownTestCase() +{ +} + +void UIBoxProgressTest::SetUp() +{ + if (boxProgress_ == nullptr) { + boxProgress_ = new UIBoxProgress(); + } +} + +void UIBoxProgressTest::TearDown() +{ + if (boxProgress_ != nullptr) { + delete boxProgress_; + boxProgress_ = nullptr; + } +} + +/** + * @tc.name: UIBoxProgressGetViewType_001 + * @tc.desc: Verify GetViewType function, equal. + * @tc.type: FUNC + * @tc.require: AR000DSMQG + */ +HWTEST_F(UIBoxProgressTest, UIBoxProgressGetViewType_001, TestSize.Level0) +{ + if (boxProgress_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + EXPECT_EQ(boxProgress_->GetViewType(), UI_BOX_PROGRESS); +} + +/** + * @tc.name: UIBoxProgressSetDirection_001 + * @tc.desc: Verify SetDirection function, equal. + * @tc.type: FUNC + * @tc.require: AR000DSMQG + */ +HWTEST_F(UIBoxProgressTest, UIBoxProgressSetDirection_001, TestSize.Level0) +{ + if (boxProgress_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + UIBoxProgress::Direction direction = UIBoxProgress::Direction::DIR_BOTTOM_TO_TOP; + boxProgress_->SetDirection(direction); + EXPECT_EQ(boxProgress_->GetDirection(), direction); + direction = UIBoxProgress::Direction::DIR_LEFT_TO_RIGHT; + boxProgress_->SetDirection(direction); + EXPECT_EQ(boxProgress_->GetDirection(), direction); + direction = UIBoxProgress::Direction::DIR_RIGHT_TO_LEFT; + boxProgress_->SetDirection(direction); + EXPECT_EQ(boxProgress_->GetDirection(), direction); + direction = UIBoxProgress::Direction::DIR_TOP_TO_BOTTOM; + boxProgress_->SetDirection(direction); + EXPECT_EQ(boxProgress_->GetDirection(), direction); +} + +/** + * @tc.name: UIBoxProgressSetValidWidth_001 + * @tc.desc: Verify SetValidWidth function, equal. + * @tc.type: FUNC + * @tc.require: AR000DSMQG + */ +HWTEST_F(UIBoxProgressTest, UIBoxProgressSetValidWidth_001, TestSize.Level0) +{ + if (boxProgress_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + const int16_t valueWidth = 10; + boxProgress_->Resize(WIDTH, HEIGHT); + EXPECT_EQ(boxProgress_->GetValidWidth(), WIDTH); + boxProgress_->SetValidWidth(valueWidth); + EXPECT_EQ(boxProgress_->GetValidWidth(), valueWidth); +} + +/** + * @tc.name: UIBoxProgressSetValidHeight_001 + * @tc.desc: Verify SetValidHeight function, equal. + * @tc.type: FUNC + * @tc.require: AR000DSMQG + */ +HWTEST_F(UIBoxProgressTest, UIBoxProgressSetValidHeight_001, TestSize.Level0) +{ + if (boxProgress_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + const int16_t valueHeight = 10; + boxProgress_->Resize(WIDTH, HEIGHT); + EXPECT_EQ(boxProgress_->GetValidHeight(), HEIGHT); + boxProgress_->SetValidHeight(valueHeight); + EXPECT_EQ(boxProgress_->GetValidHeight(), valueHeight); +} + +/** + * @tc.name: UIBoxProgressSetValue_001 + * @tc.desc: Verify SetValue function, equal. + * @tc.type: FUNC + * @tc.require: AR000DSMQG + */ +HWTEST_F(UIBoxProgressTest, UIBoxProgressSetValue_001, TestSize.Level0) +{ + if (boxProgress_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + boxProgress_->SetRange(MAX, MIN); + + int16_t value = MIN - 1; + boxProgress_->SetValue(value); + EXPECT_EQ(boxProgress_->GetValue(), MIN); + + value = MAX + 1; + boxProgress_->SetValue(value); + EXPECT_EQ(boxProgress_->GetValue(), MAX); +} + +/** + * @tc.name: UIBoxProgressSetWidth_001 + * @tc.desc: Verify SetWidth function, equal. + * @tc.type: FUNC + * @tc.require: AR000DSMQG + */ +HWTEST_F(UIBoxProgressTest, UIBoxProgressSetWidth_001, TestSize.Level0) +{ + if (boxProgress_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + + boxProgress_->SetWidth(WIDTH); + EXPECT_EQ(boxProgress_->GetWidth(), WIDTH); + EXPECT_EQ(boxProgress_->GetValidWidth(), WIDTH); +} + +/** + * @tc.name: UIBoxProgressSetHeight_001 + * @tc.desc: Verify SetHeight function, equal. + * @tc.type: FUNC + * @tc.require: AR000DSMQG + */ +HWTEST_F(UIBoxProgressTest, UIBoxProgressSetHeight_001, TestSize.Level0) +{ + if (boxProgress_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + + boxProgress_->SetHeight(HEIGHT); + EXPECT_EQ(boxProgress_->GetHeight(), HEIGHT); + EXPECT_EQ(boxProgress_->GetValidHeight(), HEIGHT); +} +} // namespace OHOS \ No newline at end of file diff --git a/test/unittest/components/ui_button_unit_test.cpp b/test/unittest/components/ui_button_unit_test.cpp new file mode 100755 index 0000000..58249c3 --- /dev/null +++ b/test/unittest/components/ui_button_unit_test.cpp @@ -0,0 +1,340 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "components/ui_button.h" + +#include +#include +#include "test_resource_config.h" + +using namespace testing::ext; + +namespace OHOS { +namespace { + const Point INIT_POS = { 10, 12 }; +} +class UIButtonTest : public testing::Test { +public: + UIButtonTest() : button_(nullptr) {} + virtual ~UIButtonTest() {} + static void SetUpTestCase() {} + static void TearDownTestCase() {} + void TearDown(); + void SetUp(); + UIButton* button_; +}; + +void UIButtonTest::SetUp() +{ + if (button_ == nullptr) { + button_ = new UIButton(); + } +} + +void UIButtonTest::TearDown() +{ + if (button_ != nullptr) { + delete button_; + button_ = nullptr; + } +} + +/** + * @tc.name: UIButtonGetViewType_001 + * @tc.desc: Verify GetViewType function. + * @tc.type: FUNC + * @tc.require: SR000DRSH1 + */ +HWTEST_F(UIButtonTest, UIButtonGetViewType_001, TestSize.Level1) +{ + if (button_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + EXPECT_EQ(button_->GetViewType(), UI_BUTTON); +} + +/** + * @tc.name: UIButtonSetImageSrc_001 + * @tc.desc: Verify SetImageSrc function. + * @tc.type: FUNC + * @tc.require: SR000DRSH1 + */ +HWTEST_F(UIButtonTest, UIButtonSetImageSrc_001, TestSize.Level0) +{ + if (button_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + button_->SetImageSrc(BLUE_RGB888_IMAGE_PATH, BLUE_RGB565_IMAGE_PATH); + ASSERT_TRUE(button_->GetCurImageSrc()); + + if (button_->GetCurImageSrc()->GetPath() == nullptr) { + EXPECT_NE(0, 0); + return; + } + EXPECT_EQ(strcmp(button_->GetCurImageSrc()->GetPath(), BLUE_RGB888_IMAGE_PATH), 0); + PressEvent event(INIT_POS); + button_->OnPressEvent(event); + if (button_->GetCurImageSrc()->GetPath() == nullptr) { + EXPECT_NE(0, 0); + return; + } + EXPECT_EQ(strcmp(button_->GetCurImageSrc()->GetPath(), BLUE_RGB565_IMAGE_PATH), 0); +} + +/** + * @tc.name:UIButtonSetImagePosition_001 + * @tc.desc: Verify SetImagePosition function. + * @tc.type: FUNC + * @tc.require: SR000DRSH1 + */ +HWTEST_F(UIButtonTest, UIButtonSetImagePosition_001, TestSize.Level0) +{ + if (button_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + button_->SetImagePosition(INIT_POS.x, INIT_POS.y); + EXPECT_EQ(button_->GetImageX(), INIT_POS.x); + EXPECT_EQ(button_->GetImageY(), INIT_POS.y); +} + +/** + * @tc.name: UIButtonSetStyle_001 + * @tc.desc: Verify SetStyle function. + * @tc.type: FUNC + * @tc.require: SR000DRSH1 + */ +HWTEST_F(UIButtonTest, UIButtonSetStyle_001, TestSize.Level0) +{ + if (button_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + button_->SetStateForStyle(UIButton::ButtonState::PRESSED); + button_->SetStyle(STYLE_BACKGROUND_COLOR, Color::Blue().full); + EXPECT_EQ(button_->GetStyle(STYLE_BACKGROUND_COLOR), Color::Blue().full); + EXPECT_EQ(button_->GetStyleForState(STYLE_BACKGROUND_COLOR, UIButton::ButtonState::PRESSED), Color::Blue().full); +} + +/** + * @tc.name: UIButtonSetStyle_002 + * @tc.desc: Verify SetStyle function. + * @tc.type: FUNC + * @tc.require: SR000DRSH1 + */ +HWTEST_F(UIButtonTest, UIButtonSetStyle_002, TestSize.Level0) +{ + if (button_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + button_->SetStateForStyle(UIButton::ButtonState::INACTIVE); + button_->SetStyle(STYLE_BACKGROUND_COLOR, Color::Red().full); + EXPECT_EQ(button_->GetStyle(STYLE_BACKGROUND_COLOR), Color::Red().full); + EXPECT_EQ(button_->GetStyleForState(STYLE_BACKGROUND_COLOR, UIButton::ButtonState::INACTIVE), Color::Red().full); +} + +/** + * @tc.name: UIButtonSetStyle_003 + * @tc.desc: Verify SetStyle function. + * @tc.type: FUNC + * @tc.require: SR000DRSH1 + */ +HWTEST_F(UIButtonTest, UIButtonSetStyle_003, TestSize.Level0) +{ + if (button_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + button_->SetStateForStyle(UIButton::ButtonState::RELEASED); + button_->SetStyle(STYLE_BACKGROUND_COLOR, Color::Green().full); + EXPECT_EQ(button_->GetStyle(STYLE_BACKGROUND_COLOR), Color::Green().full); + EXPECT_EQ(button_->GetStyleForState(STYLE_BACKGROUND_COLOR, UIButton::ButtonState::RELEASED), Color::Green().full); +} + +/** + * @tc.name: UIButtonIsTouchable_001 + * @tc.desc: Verify IsTouchable function, equal. + * @tc.type: FUNC + * @tc.require: SR000DRSH1 + */ +HWTEST_F(UIButtonTest, UIButtonIsTouchable_001, TestSize.Level0) +{ + if (button_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + button_->Enable(); + EXPECT_EQ(button_->IsTouchable(), true); + button_->Disable(); + EXPECT_EQ(button_->IsTouchable(), false); +} + +/** + * @tc.name: UIButtonSetSize_001 + * @tc.desc: Verify SetSize function, equal. + * @tc.type: FUNC + * @tc.require: SR000DRSH1 + */ +HWTEST_F(UIButtonTest, UIButtonSetSize_001, TestSize.Level0) +{ + if (button_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + const int16_t releasedWidth = 5; + const int16_t releasedHeight = 25; + const int16_t paddingdLeft = 10; + const int16_t paddingdTop = 20; + const int16_t borderWidth = 2; + const int16_t posX = 50; + const int16_t posY = 100; + button_->SetStyleForState(STYLE_PADDING_LEFT, paddingdLeft, UIButton::ButtonState::RELEASED); + button_->SetStyleForState(STYLE_BORDER_WIDTH, borderWidth, UIButton::ButtonState::RELEASED); + button_->SetStyleForState(STYLE_PADDING_TOP, paddingdTop, UIButton::ButtonState::RELEASED); + + ReleaseEvent releaseEvent(INIT_POS); + button_->OnReleaseEvent(releaseEvent); +button_->SetPosition(posX, posY); + button_->SetWidth(releasedWidth); + button_->SetHeight(releasedHeight); + EXPECT_EQ(button_->GetWidth(), releasedWidth); + EXPECT_EQ(button_->GetHeight(), releasedHeight); + EXPECT_EQ(button_->GetContentRect().GetWidth(), releasedWidth); + EXPECT_EQ(button_->GetContentRect().GetHeight(), releasedHeight); + EXPECT_EQ(button_->GetContentRect().GetX(), posX + paddingdLeft + borderWidth); + EXPECT_EQ(button_->GetContentRect().GetY(), posY + paddingdTop + borderWidth); +} + +/** + * @tc.name: UIButtonSetSize_002 + * @tc.desc: Verify SetSize function, equal. + * @tc.type: FUNC + * @tc.require: SR000DRSH1 + */ +HWTEST_F(UIButtonTest, UIButtonSetSize_002, TestSize.Level0) +{ + if (button_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + const int16_t pressWidth = 5; + const int16_t pressHeight = 25; + const int16_t paddingdLeft = 10; + const int16_t paddingdTop = 20; + const int16_t borderWidth = 2; + const int16_t posX = 50; + const int16_t posY = 100; + button_->SetStyleForState(STYLE_PADDING_LEFT, paddingdLeft, UIButton::ButtonState::PRESSED); + button_->SetStyleForState(STYLE_BORDER_WIDTH, borderWidth, UIButton::ButtonState::PRESSED); + button_->SetStyleForState(STYLE_PADDING_TOP, paddingdTop, UIButton::ButtonState::PRESSED); + + PressEvent pressEvent(INIT_POS); + button_->OnPressEvent(pressEvent); + button_->SetPosition(posX, posY); + button_->SetWidth(pressWidth); + button_->SetHeight(pressHeight); + EXPECT_EQ(button_->GetWidth(), pressWidth); + EXPECT_EQ(button_->GetHeight(), pressHeight); + EXPECT_EQ(button_->GetContentRect().GetWidth(), pressWidth); + EXPECT_EQ(button_->GetContentRect().GetHeight(), pressHeight); + EXPECT_EQ(button_->GetContentRect().GetX(), posX + paddingdLeft + borderWidth); + EXPECT_EQ(button_->GetContentRect().GetY(), posY + paddingdTop + borderWidth); +} + +/** + * @tc.name: UIButtonSetSize_003 + * @tc.desc: Verify SetSize function, equal. + * @tc.type: FUNC + * @tc.require: SR000DRSH1 + */ +HWTEST_F(UIButtonTest, UIButtonSetSize_003, TestSize.Level0) +{ + if (button_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + const int16_t inactiveWidth = 5; + const int16_t inactiveHeight = 25; + const int16_t paddingdLeft = 10; + const int16_t paddingdTop = 20; + const int16_t borderWidth = 2; + const int16_t posX = 50; + const int16_t posY = 100; + button_->SetStyleForState(STYLE_PADDING_LEFT, paddingdLeft, UIButton::ButtonState::INACTIVE); + button_->SetStyleForState(STYLE_BORDER_WIDTH, borderWidth, UIButton::ButtonState::INACTIVE); + button_->SetStyleForState(STYLE_PADDING_TOP, paddingdTop, UIButton::ButtonState::INACTIVE); + + button_->Disable(); + button_->SetPosition(posX, posY); + button_->SetWidth(inactiveWidth); + button_->SetHeight(inactiveHeight); + EXPECT_EQ(button_->GetWidth(), inactiveWidth); + EXPECT_EQ(button_->GetHeight(), inactiveHeight); + EXPECT_EQ(button_->GetContentRect().GetWidth(), inactiveWidth); + EXPECT_EQ(button_->GetContentRect().GetHeight(), inactiveHeight); + EXPECT_EQ(button_->GetContentRect().GetX(), posX + paddingdLeft + borderWidth); + EXPECT_EQ(button_->GetContentRect().GetY(), posY + paddingdTop + borderWidth); +} + +/** + * @tc.name: UIButtonSetStyleForState_001 + * @tc.desc: Verify SetStyleForState function, equal. + * @tc.type: FUNC + * @tc.require: SR000DRSH1 + */ +HWTEST_F(UIButtonTest, UIButtonSetStyleForState_001, TestSize.Level0) +{ + if (button_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + button_->SetStyleForState(STYLE_BACKGROUND_COLOR, Color::Red().full, UIButton::ButtonState::RELEASED); + EXPECT_EQ(button_->GetStyleForState(STYLE_BACKGROUND_COLOR, UIButton::ButtonState::RELEASED), + Color::Red().full); + button_->SetStyleForState(STYLE_BACKGROUND_COLOR, Color::Green().full, UIButton::ButtonState::PRESSED); + EXPECT_EQ(button_->GetStyleForState(STYLE_BACKGROUND_COLOR, UIButton::ButtonState::PRESSED), + Color::Green().full); + button_->SetStyleForState(STYLE_BACKGROUND_COLOR, Color::Yellow().full, UIButton::ButtonState::INACTIVE); + EXPECT_EQ(button_->GetStyleForState(STYLE_BACKGROUND_COLOR, UIButton::ButtonState::INACTIVE), + Color::Yellow().full); +} + +/** + * @tc.name: UIButtonSetStateForStyle_001 + * @tc.desc: Verify SetStyle function. + * @tc.type: FUNC + * @tc.require: SR000DRSH1 + */ +HWTEST_F(UIButtonTest, UIButtonSetStateForStyle_001, TestSize.Level0) +{ + if (button_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + button_->SetStyleForState(STYLE_BACKGROUND_COLOR, Color::Red().full, UIButton::ButtonState::RELEASED); + EXPECT_EQ(button_->GetStyleForState(STYLE_BACKGROUND_COLOR, UIButton::ButtonState::RELEASED), + Color::Red().full); + button_->SetStyleForState(STYLE_BACKGROUND_COLOR, Color::Green().full, UIButton::ButtonState::PRESSED); + EXPECT_EQ(button_->GetStyleForState(STYLE_BACKGROUND_COLOR, UIButton::ButtonState::PRESSED), + Color::Green().full); + button_->SetStateForStyle(UIButton::ButtonState::RELEASED); + EXPECT_EQ(button_->GetStyle(STYLE_BACKGROUND_COLOR), Color::Red().full); + button_->SetStateForStyle(UIButton::ButtonState::PRESSED); + EXPECT_EQ(button_->GetStyle(STYLE_BACKGROUND_COLOR), Color::Green().full); +} +} // namespace OHOS \ No newline at end of file diff --git a/test/unittest/components/ui_canvas_unit_test.cpp b/test/unittest/components/ui_canvas_unit_test.cpp new file mode 100755 index 0000000..7ee1aeb --- /dev/null +++ b/test/unittest/components/ui_canvas_unit_test.cpp @@ -0,0 +1,567 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "components/root_view.h" +#include "components/ui_canvas.h" +#include "components/ui_view_group.h" + +#include +#include + +using namespace testing::ext; +namespace OHOS { +namespace { + const int16_t POS_X = 50; + const int16_t POS_Y = 100; + const uint16_t WIDTH = 100; + const uint16_t HEIGHT = 100; + const int16_t START1_X = 10; + const int16_t START1_Y = 20; + const int16_t LINE1_X = 40; + const int16_t LINE1_Y = 100; + const int16_t LINE2_X = 50; + const int16_t LINE2_Y = 120; + const int16_t CENTER_X = 150; + const int16_t CENTER_Y = 150; + const int16_t RADIUS = 50; + const int16_t START_ANGLE = 30; + const int16_t END_ANGLE = 250; + const int16_t RECT_X = 250; + const int16_t RECT_Y = 50; + const int16_t RECT_WIDTH = 100; + const int16_t RECT_HEIGHT = 50; +} + +class TestUICanvas : public UICanvas { +public: + TestUICanvas() {} + virtual ~TestUICanvas() {} + + const UICanvasPath* GetPath() const + { + return path_; + } + + Point GetStartPos() const + { + if (path_ != nullptr) { + return path_->startPos_; + } else { + return { COORD_MIN, COORD_MIN }; + } + } + + Point GetEndPos() const + { + if (path_ != nullptr) { + return path_->points_.Tail()->data_; + } else { + return { COORD_MIN, COORD_MIN }; + } + } +}; + +class UICanvasTest : public testing::Test { +public: + static void SetUpTestCase() {} + static void TearDownTestCase() {} + void SetUp(); + void TearDown(); + static Paint* paint_; + static TestUICanvas* canvas_; +}; + +Paint* UICanvasTest::paint_ = nullptr; +TestUICanvas* UICanvasTest::canvas_ = nullptr; + +void UICanvasTest::SetUp() +{ + if (paint_ == nullptr) { + paint_ = new Paint(); + } + if (canvas_ == nullptr) { + canvas_ = new TestUICanvas(); + } +} + +void UICanvasTest::TearDown() +{ + if (paint_ != nullptr) { + delete paint_; + paint_ = nullptr; + } + if (canvas_ != nullptr) { + delete canvas_; + canvas_ = nullptr; + } +} +/** + * @tc.name: UICanvasSetPaintStyle_001 + * @tc.desc: Verify SetStyle function, equal. + * @tc.type: FUNC + * @tc.require: AR000DSMPV + */ +HWTEST_F(UICanvasTest, UICanvasSetPaintStyle_001, TestSize.Level1) +{ + if (paint_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + Paint::PaintStyle paintStyle = Paint::PaintStyle::FILL_STYLE; + + paint_->SetStyle(Paint::PaintStyle::FILL_STYLE); + EXPECT_EQ(paint_->GetStyle(), paintStyle); +} + +/** + * @tc.name: UICanvasSetStrokeWidth_001 + * @tc.desc: Verify SetStrokeWidth function, equal. + * @tc.type: FUNC + * @tc.require: AR000DSMPV + */ +HWTEST_F(UICanvasTest, UICanvasSetStrokeWidth_001, TestSize.Level0) +{ + if (paint_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + paint_->SetStrokeWidth(WIDTH); + EXPECT_EQ(paint_->GetStrokeWidth(), WIDTH); +} + +/** + * @tc.name: UICanvasSetStrokeColor_001 + * @tc.desc: Verify SetStrokeColor function, equal. + * @tc.type: FUNC + * @tc.require: AR000DSMPV + */ +HWTEST_F(UICanvasTest, UICanvasSetStrokeColor_001, TestSize.Level0) +{ + if (paint_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + ColorType color = Color::Red(); + + paint_->SetStrokeColor(color); + EXPECT_EQ(paint_->GetStrokeColor().full, color.full); +} + +/** + * @tc.name: UICanvasSetFillColor_001 + * @tc.desc: Verify SetFillColor function, equal. + * @tc.type: FUNC + * @tc.require: AR000DSMPV + */ +HWTEST_F(UICanvasTest, UICanvasSetFillColor_001, TestSize.Level0) +{ + if (paint_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + ColorType color = Color::Red(); + + paint_->SetFillColor(color); + EXPECT_EQ(paint_->GetFillColor().full, color.full); +} + +/** + * @tc.name: UICanvasSetOpacity_001 + * @tc.desc: Verify SetOpacity function, equal. + * @tc.type: FUNC + * @tc.require: AR000DSMPV + */ +HWTEST_F(UICanvasTest, UICanvasSetOpacity_001, TestSize.Level0) +{ + if (paint_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + paint_->SetOpacity(OPA_OPAQUE); + EXPECT_EQ(paint_->GetOpacity(), OPA_OPAQUE); +} + +/** + * @tc.name: UICanvasSetStartPosition_001 + * @tc.desc: Verify SetStartPosition function, equal. + * @tc.type: FUNC + * @tc.require: AR000DSMPV + */ +HWTEST_F(UICanvasTest, UICanvasSetStartPosition_001, TestSize.Level0) +{ + if (canvas_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + canvas_->SetStartPosition({ POS_X, POS_Y }); + EXPECT_EQ(canvas_->GetStartPosition().x, POS_X); + EXPECT_EQ(canvas_->GetStartPosition().y, POS_Y); +} + +/** + * @tc.name: UICanvasDrawLine_001 + * @tc.desc: Verify DrawLine function, equal. + * @tc.type: FUNC + * @tc.require: AR000DSMPV + */ +HWTEST_F(UICanvasTest, UICanvasDrawLine_001, TestSize.Level0) +{ + if (canvas_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + RootView* rootView = RootView::GetInstance(); + UIViewGroup* viewGroup = static_cast(rootView); + Paint paint; + Point startPoint = { 0, 50 }; + Point endPoint = { 50, 100 }; + + viewGroup->SetPosition(0, 0); + viewGroup->SetWidth(WIDTH); + viewGroup->SetHeight(HEIGHT); + canvas_->DrawLine(startPoint, endPoint, paint); + viewGroup->Add(canvas_); + EXPECT_EQ(canvas_->GetStartPosition().x, endPoint.x); + EXPECT_EQ(canvas_->GetStartPosition().y, endPoint.y); + viewGroup->Remove(canvas_); +} + +/** + * @tc.name: UICanvasDrawCurve_001 + * @tc.desc: Verify DrawCurve function, equal. + * @tc.type: FUNC + * @tc.require: AR000DSMPV + */ +HWTEST_F(UICanvasTest, UICanvasDrawCurve_001, TestSize.Level0) +{ + if (canvas_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + RootView* rootView = RootView::GetInstance(); + UIViewGroup* viewGroup = static_cast(rootView); + Paint paint; + Point startPoint = { 100, 100 }; + Point endPoint = { 150, 200 }; + Point control1Point = { 150, 100 }; + Point control2Point = { 150, 100 }; + + viewGroup->SetPosition(0, 0); + viewGroup->SetWidth(WIDTH); + viewGroup->SetHeight(HEIGHT); + canvas_->DrawCurve(startPoint, control1Point, control2Point, endPoint, paint); + viewGroup->Add(canvas_); + EXPECT_EQ(canvas_->GetStartPosition().x, endPoint.x); + EXPECT_EQ(canvas_->GetStartPosition().y, endPoint.y); + viewGroup->Remove(canvas_); +} + +/** + * @tc.name: UICanvasBeginPath_001 + * @tc.desc: Verify BeginPath function, equal. + * @tc.type: FUNC + * @tc.require: AR000EVN8V + */ +HWTEST_F(UICanvasTest, UICanvasBeginPath_001, TestSize.Level0) +{ + if (canvas_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + + EXPECT_EQ(canvas_->GetPath(), nullptr); + canvas_->BeginPath(); + EXPECT_NE(canvas_->GetPath(), nullptr); +} + +/** + * @tc.name: UICanvasMoveTo_001 + * @tc.desc: Verify MoveTo function, equal. + * @tc.type: FUNC + * @tc.require: AR000EVN8V + */ +HWTEST_F(UICanvasTest, UICanvasMoveTo_001, TestSize.Level0) +{ + if (canvas_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + canvas_->BeginPath(); + canvas_->MoveTo({ START1_X, START1_Y }); + Point start = canvas_->GetStartPos(); + EXPECT_EQ(start.x, START1_X); + EXPECT_EQ(start.y, START1_Y); + + Point end = canvas_->GetEndPos(); + EXPECT_EQ(end.x, START1_X); + EXPECT_EQ(end.y, START1_Y); +} + +/** + * @tc.name: UICanvasLineTo_001 + * @tc.desc: Verify LineTo function, equal. + * @tc.type: FUNC + * @tc.require: AR000EVN8V + */ +HWTEST_F(UICanvasTest, UICanvasLineTo_001, TestSize.Level0) +{ + if (canvas_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + canvas_->BeginPath(); + canvas_->LineTo({ LINE1_X, LINE1_Y }); + Point start = canvas_->GetStartPos(); + EXPECT_EQ(start.x, LINE1_X); + EXPECT_EQ(start.y, LINE1_Y); + + Point end = canvas_->GetEndPos(); + EXPECT_EQ(end.x, LINE1_X); + EXPECT_EQ(end.y, LINE1_Y); +} + +/** + * @tc.name: UICanvasLineTo_002 + * @tc.desc: Verify LineTo function, equal. + * @tc.type: FUNC + * @tc.require: AR000EVN8V + */ +HWTEST_F(UICanvasTest, UICanvasLineTo_002, TestSize.Level0) +{ + if (canvas_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + canvas_->BeginPath(); + canvas_->MoveTo({ START1_X, START1_Y }); + canvas_->LineTo({ LINE1_X, LINE1_Y }); + Point start = canvas_->GetStartPos(); + EXPECT_EQ(start.x, START1_X); + EXPECT_EQ(start.y, START1_Y); + + Point end = canvas_->GetEndPos(); + EXPECT_EQ(end.x, LINE1_X); + EXPECT_EQ(end.y, LINE1_Y); + + canvas_->LineTo({ LINE2_X, LINE2_Y }); + end = canvas_->GetEndPos(); + EXPECT_EQ(end.x, LINE2_X); + EXPECT_EQ(end.y, LINE2_Y); +} + +/** + * @tc.name: UICanvasArcTo_001 + * @tc.desc: Verify ArcTo function, equal. + * @tc.type: FUNC + * @tc.require: AR000EVN8V + */ +HWTEST_F(UICanvasTest, UICanvasArcTo_001, TestSize.Level0) +{ + if (canvas_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + canvas_->BeginPath(); + canvas_->ArcTo({ CENTER_X, CENTER_Y }, RADIUS, START_ANGLE, END_ANGLE); + + float sinma = RADIUS * Sin(START_ANGLE); + float cosma = RADIUS * Sin(QUARTER_IN_DEGREE - START_ANGLE); + Point start = canvas_->GetStartPos(); + EXPECT_EQ(start.x, MATH_ROUND(CENTER_X + sinma)); + EXPECT_EQ(start.y, MATH_ROUND(CENTER_Y - cosma)); + + sinma = RADIUS * Sin(END_ANGLE); + cosma = RADIUS * Sin(QUARTER_IN_DEGREE - END_ANGLE); + Point end = canvas_->GetEndPos(); + EXPECT_EQ(end.x, MATH_ROUND(CENTER_X + sinma)); + EXPECT_EQ(end.y, MATH_ROUND(CENTER_Y - cosma)); +} + +/** + * @tc.name: UICanvasArcTo_002 + * @tc.desc: Verify ArcTo function, equal. + * @tc.type: FUNC + * @tc.require: AR000EVN8V + */ +HWTEST_F(UICanvasTest, UICanvasArcTo_002, TestSize.Level0) +{ + if (canvas_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + canvas_->BeginPath(); + canvas_->ArcTo({ CENTER_X, CENTER_Y }, RADIUS, START_ANGLE, START_ANGLE + CIRCLE_IN_DEGREE + QUARTER_IN_DEGREE); + + float sinma = RADIUS * Sin(START_ANGLE); + float cosma = RADIUS * Sin(QUARTER_IN_DEGREE - START_ANGLE); + Point start = canvas_->GetStartPos(); + EXPECT_EQ(start.x, MATH_ROUND(CENTER_X + sinma)); + EXPECT_EQ(start.y, MATH_ROUND(CENTER_Y - cosma)); + + sinma = RADIUS * Sin(END_ANGLE); + cosma = RADIUS * Sin(QUARTER_IN_DEGREE - END_ANGLE); + Point end = canvas_->GetEndPos(); + EXPECT_EQ(end.x, start.x); + EXPECT_EQ(end.y, start.y); +} + +/** + * @tc.name: UICanvasArcTo_003 + * @tc.desc: Verify ArcTo function, equal. + * @tc.type: FUNC + * @tc.require: AR000EVN8V + */ +HWTEST_F(UICanvasTest, UICanvasArcTo_003, TestSize.Level0) +{ + if (canvas_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + canvas_->BeginPath(); + canvas_->MoveTo({ START1_X, START1_Y }); + canvas_->ArcTo({ CENTER_X, CENTER_Y }, RADIUS, START_ANGLE, END_ANGLE); + + Point start = canvas_->GetStartPos(); + EXPECT_EQ(start.x, START1_X); + EXPECT_EQ(start.y, START1_Y); + + float sinma = RADIUS * Sin(END_ANGLE); + float cosma = RADIUS * Sin(QUARTER_IN_DEGREE - END_ANGLE); + Point end = canvas_->GetEndPos(); + EXPECT_EQ(end.x, MATH_ROUND(CENTER_X + sinma)); + EXPECT_EQ(end.y, MATH_ROUND(CENTER_Y - cosma)); +} + +/** + * @tc.name: UICanvasAddRect_001 + * @tc.desc: Verify AddRect function, equal. + * @tc.type: FUNC + * @tc.require: AR000EVN8V + */ +HWTEST_F(UICanvasTest, UICanvasAddRect_001, TestSize.Level0) +{ + if (canvas_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + canvas_->BeginPath(); + canvas_->AddRect({ RECT_X, RECT_Y }, RECT_HEIGHT, RECT_WIDTH); + + Point start = canvas_->GetStartPos(); + EXPECT_EQ(start.x, RECT_X); + EXPECT_EQ(start.y, RECT_Y); + + Point end = canvas_->GetEndPos(); + EXPECT_EQ(end.x, RECT_X); + EXPECT_EQ(end.y, RECT_Y); +} + +/** + * @tc.name: UICanvasAddRect_002 + * @tc.desc: Verify AddRect function, equal. + * @tc.type: FUNC + * @tc.require: AR000EVN8V + */ +HWTEST_F(UICanvasTest, UICanvasAddRect_002, TestSize.Level0) +{ + if (canvas_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + canvas_->BeginPath(); + canvas_->MoveTo({ START1_X, START1_Y }); + canvas_->LineTo({ LINE1_X, LINE1_Y }); + canvas_->AddRect({ RECT_X, RECT_Y }, RECT_HEIGHT, RECT_WIDTH); + + Point start = canvas_->GetStartPos(); + EXPECT_EQ(start.x, RECT_X); + EXPECT_EQ(start.y, RECT_Y); + + Point end = canvas_->GetEndPos(); + EXPECT_EQ(end.x, RECT_X); + EXPECT_EQ(end.y, RECT_Y); +} + +/** + * @tc.name: UICanvasClosePath_001 + * @tc.desc: Verify ClosePath function, equal. + * @tc.type: FUNC + * @tc.require: AR000EVN8V + */ +HWTEST_F(UICanvasTest, UICanvasClosePath_001, TestSize.Level0) +{ + if (canvas_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + canvas_->BeginPath(); + canvas_->MoveTo({ START1_X, START1_Y }); + canvas_->LineTo({ LINE1_X, LINE1_Y }); + canvas_->ClosePath(); + + Point start = canvas_->GetStartPos(); + EXPECT_EQ(start.x, START1_X); + EXPECT_EQ(start.y, START1_Y); + + Point end = canvas_->GetEndPos(); + EXPECT_EQ(end.x, START1_X); + EXPECT_EQ(end.y, START1_Y); +} + +/** + * @tc.name: UICanvasClosePath_002 + * @tc.desc: Verify ClosePath function, equal. + * @tc.type: FUNC + * @tc.require: SR000EVN8R + */ +HWTEST_F(UICanvasTest, UICanvasClosePath_002, TestSize.Level0) +{ + if (canvas_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + + if (paint_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + + canvas_->BeginPath(); + canvas_->MoveTo({ START1_X, START1_Y }); + canvas_->LineTo({ LINE1_X, LINE1_Y }); + canvas_->ClosePath(); + canvas_->DrawPath(*paint_); + + Point start = canvas_->GetStartPos(); + EXPECT_EQ(start.x, START1_X); + EXPECT_EQ(start.y, START1_Y); + + Point end = canvas_->GetEndPos(); + EXPECT_EQ(end.x, START1_X); + EXPECT_EQ(end.y, START1_Y); + + canvas_->BeginPath(); + canvas_->LineTo({ LINE2_X, LINE2_Y }); + canvas_->ClosePath(); + + start = canvas_->GetStartPos(); + EXPECT_EQ(start.x, LINE2_X); + EXPECT_EQ(start.y, LINE2_Y); + + end = canvas_->GetEndPos(); + EXPECT_EQ(end.x, LINE2_X); + EXPECT_EQ(end.y, LINE2_Y); +} +} // namespace OHOS \ No newline at end of file diff --git a/test/unittest/components/ui_chart_unit_test.cpp b/test/unittest/components/ui_chart_unit_test.cpp new file mode 100755 index 0000000..98a89b1 --- /dev/null +++ b/test/unittest/components/ui_chart_unit_test.cpp @@ -0,0 +1,491 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "components/ui_chart.h" +#include +#include + +using namespace testing::ext; + +namespace OHOS { +namespace { + const uint16_t ARRAY_SIZE = 5; + const uint16_t RADIUS = 5; + const uint16_t WIDTH = 10; + const Point POINT_ARRAY[ARRAY_SIZE] = { {0, 2478}, {1, 2600}, {2, 3000}, {3, 3200}, {4, 3500} }; +} + +class UIChartDataSerialTest : public testing::Test { +public: + UIChartDataSerialTest() : chartDataSerial_(nullptr), chart_(nullptr) {} + ~UIChartDataSerialTest() {} + static void SetUpTestCase(void) {} + static void TearDownTestCase(void) {} + void SetUp(void); + void TearDowm(void); + UIChartDataSerial* chartDataSerial_; + UIChartPillar* chart_; +}; + +void UIChartDataSerialTest::SetUp(void) +{ + if (chartDataSerial_ == nullptr) { + chartDataSerial_ = new UIChartDataSerial(); + chartDataSerial_->SetMaxDataCount(ARRAY_SIZE); + } + if (chart_ == nullptr) { + chart_ = new UIChartPillar(); + } +} + +void UIChartDataSerialTest::TearDowm(void) +{ + if (chartDataSerial_ != nullptr) { + delete chartDataSerial_; + chartDataSerial_ = nullptr; + } + if (chart_ != nullptr) { + delete chart_; + chart_ = nullptr; + } +} + +void InitPointStyle(UIChartDataSerial::PointStyle& pointStyle) +{ + pointStyle.fillColor = Color::Red(); + pointStyle.radius = RADIUS; + pointStyle.strokeColor = Color::White(); + pointStyle.strokeWidth = WIDTH; +} + +/** + * @tc.name: UIChartDataSerialSetMaxDataCount_001 + * @tc.desc: Verify SetMaxDataCount function, equal. + * @tc.type: FUNC + * @tc.require: AR000EEMQ8 + */ +HWTEST_F(UIChartDataSerialTest, UIChartDataSerialSetMaxDataCount_001, TestSize.Level0) +{ + if (chartDataSerial_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + EXPECT_EQ(chartDataSerial_->SetMaxDataCount(1), true); +} + +/** + * @tc.name: UIChartDataSerialAddPoints_001 + * @tc.desc: Verify AddPoints function, equal. + * @tc.type: FUNC + * @tc.require: AR000EEMQ8 + */ +HWTEST_F(UIChartDataSerialTest, UIChartDataSerialAddPoints_001, TestSize.Level0) +{ + if (chartDataSerial_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + bool ret = chartDataSerial_->AddPoints(nullptr, 0); + EXPECT_EQ(ret, false); + ret = chartDataSerial_->AddPoints(POINT_ARRAY, ARRAY_SIZE); + EXPECT_EQ(ret, true); + ret = chartDataSerial_->AddPoints(POINT_ARRAY, 0); + EXPECT_EQ(ret, false); +} + +/** + * @tc.name: UIChartDataSerialGetPoint_001 + * @tc.desc: Verify GetPoint function, equal. + * @tc.type: FUNC + * @tc.require: AR000EEMQ8 + */ +HWTEST_F(UIChartDataSerialTest, UIChartDataSerialGetPoint_001, TestSize.Level1) +{ + if (chartDataSerial_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + Point point; + + bool ret = chartDataSerial_->AddPoints(POINT_ARRAY, ARRAY_SIZE); + EXPECT_EQ(ret, true); + ret = chartDataSerial_->GetPoint(1, point); + EXPECT_EQ(ret, true); + EXPECT_EQ(point.x, POINT_ARRAY[1].x); + EXPECT_EQ(point.y, POINT_ARRAY[1].y); +} + +/** + * @tc.name: UIChartDataSerialModifyPoint_001 + * @tc.desc: Verify ModifyPoint function, equal. + * @tc.type: FUNC + * @tc.require: AR000EEMQ8 + */ +HWTEST_F(UIChartDataSerialTest, UIChartDataSerialModifyPoint_001, TestSize.Level0) +{ + if (chartDataSerial_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + Point point = { 1, 200 }; // 200 : y posetion + Point point1; + + bool ret = chartDataSerial_->AddPoints(POINT_ARRAY, ARRAY_SIZE); + EXPECT_EQ(ret, true); + ret = chartDataSerial_->ModifyPoint(ARRAY_SIZE + 1, point); + EXPECT_EQ(ret, false); + ret = chartDataSerial_->ModifyPoint(1, point); + EXPECT_EQ(ret, true); + ret = chartDataSerial_->GetPoint(1, point1); + EXPECT_EQ(ret, true); + EXPECT_EQ(point1.x, point.x); + EXPECT_EQ(point1.y, point.y); +} + +/** + * @tc.name: UIChartDataSerialClearData_001 + * @tc.desc: Verify ClearData function, equal. + * @tc.type: FUNC + * @tc.require: AR000EEMQ8 + */ +HWTEST_F(UIChartDataSerialTest, UIChartDataSerialClearData_001, TestSize.Level0) +{ + if (chartDataSerial_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + Point point; + + bool ret = chartDataSerial_->AddPoints(POINT_ARRAY, ARRAY_SIZE); + EXPECT_EQ(ret, true); + chartDataSerial_->ClearData(); + ret = chartDataSerial_->GetPoint(1, point); + EXPECT_EQ(ret, false); +} + +/** + * @tc.name: UIChartDataSerialGetDataCount_001 + * @tc.desc: Verify GetDataCount function, equal. + * @tc.type: FUNC + * @tc.require: AR000EEMQ8 + */ +HWTEST_F(UIChartDataSerialTest, UIChartDataSerialGetDataCount_001, TestSize.Level0) +{ + if (chartDataSerial_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + bool ret = chartDataSerial_->AddPoints(POINT_ARRAY, ARRAY_SIZE); + EXPECT_EQ(ret, true); + uint16_t count = chartDataSerial_->GetDataCount(); + EXPECT_EQ(count, ARRAY_SIZE); + chartDataSerial_->ClearData(); + count = chartDataSerial_->GetDataCount(); + EXPECT_EQ(count, 0); +} + +/** + * @tc.name: UIChartDataSerialEnableGradient_001 + * @tc.desc: Verify EnableGradient function, equal. + * @tc.type: FUNC + * @tc.require: AR000EEMQ8 + */ +HWTEST_F(UIChartDataSerialTest, UIChartDataSerialEnableGradient_001, TestSize.Level1) +{ + if (chartDataSerial_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + chartDataSerial_->EnableGradient(true); + EXPECT_EQ(chartDataSerial_->IsGradient(), true); +} + +/** + * @tc.name: UIChartDataSerialEnableSmooth_001 + * @tc.desc: Verify EnableSmooth function, equal. + * @tc.type: FUNC + * @tc.require: AR000EEMQ8 + */ +HWTEST_F(UIChartDataSerialTest, UIChartDataSerialEnableSmooth_001, TestSize.Level1) +{ + if (chartDataSerial_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + chartDataSerial_->EnableSmooth(true); + bool ret = chartDataSerial_->IsSmooth(); + EXPECT_EQ(ret, true); +} + +/** + * @tc.name: UIChartDataSerialGetPeakIndex_001 + * @tc.desc: Verify GetPeakIndex function, equal. + * @tc.type: FUNC + * @tc.require: AR000EEMQ8 + */ +HWTEST_F(UIChartDataSerialTest, UIChartDataSerialGetPeakIndex_001, TestSize.Level1) +{ + if (chartDataSerial_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + bool ret = chartDataSerial_->AddPoints(POINT_ARRAY, ARRAY_SIZE); + EXPECT_EQ(ret, true); + uint16_t index = chartDataSerial_->GetPeakIndex(); + EXPECT_EQ(index, 4); + int16_t value = chartDataSerial_->GetPeakData(); + EXPECT_EQ(value, 3500); +} + +/** + * @tc.name: UIChartDataSerialGetValleyIndex_001 + * @tc.desc: Verify GetValleyIndex function, equal. + * @tc.type: FUNC + * @tc.require: AR000EEMQ8 + */ +HWTEST_F(UIChartDataSerialTest, UIChartDataSerialGetValleyIndex_001, TestSize.Level0) +{ + if (chartDataSerial_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + bool ret = chartDataSerial_->AddPoints(POINT_ARRAY, ARRAY_SIZE); + EXPECT_EQ(ret, true); + uint16_t index = chartDataSerial_->GetValleyIndex(); + EXPECT_EQ(index, 0); +} + +/** + * @tc.name: UIChartDataSerialGetLatestIndex_001 + * @tc.desc: Verify GetLatestIndex function, equal. + * @tc.type: FUNC + * @tc.require: AR000EEMQ8 + */ +HWTEST_F(UIChartDataSerialTest, UIChartDataSerialGetLatestIndex_001, TestSize.Level0) +{ + if (chartDataSerial_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + bool ret = chartDataSerial_->AddPoints(POINT_ARRAY, ARRAY_SIZE); + EXPECT_EQ(ret, true); + uint16_t index = chartDataSerial_->GetLatestIndex(); + EXPECT_EQ(index, ARRAY_SIZE - 1); +} + +/** + * @tc.name: UIChartDataSerialSetLastPointIndex_001 + * @tc.desc: Verify SetLastPointIndex function, equal. + * @tc.type: FUNC + * @tc.require: AR000EEMQ8 + */ +HWTEST_F(UIChartDataSerialTest, UIChartDataSerialSetLastPointIndex_001, TestSize.Level1) +{ + if (chartDataSerial_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + bool ret = chartDataSerial_->AddPoints(POINT_ARRAY, ARRAY_SIZE); + EXPECT_EQ(ret, true); + uint16_t index = chartDataSerial_->GetLastPointIndex(); + EXPECT_EQ(index, 0); + const uint16_t lastPointIndex = 4; + chartDataSerial_->SetLastPointIndex(lastPointIndex); + EXPECT_EQ(chartDataSerial_->GetLastPointIndex(), lastPointIndex); +} + +/** + * @tc.name: UIChartDataSerialSetLineColor_001 + * @tc.desc: Verify SetLineColor function, equal. + * @tc.type: FUNC + * @tc.require: AR000EEMQ8 + */ +HWTEST_F(UIChartDataSerialTest, UIChartDataSerialSetLineColor_001, TestSize.Level0) +{ + if (chartDataSerial_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + ColorType color = Color::Red(); + chartDataSerial_->SetLineColor(color); + EXPECT_EQ(chartDataSerial_->GetLineColor().full, color.full); +} + +/** + * @tc.name: UIChartDataSerialSetFillColor_001 + * @tc.desc: Verify SetFillColor function, equal. + * @tc.type: FUNC + * @tc.require: AR000EEMQ8 + */ +HWTEST_F(UIChartDataSerialTest, UIChartDataSerialSetFillColor_001, TestSize.Level0) +{ + if (chartDataSerial_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + ColorType color = Color::Red(); + chartDataSerial_->SetFillColor(color); + EXPECT_EQ(chartDataSerial_->GetFillColor().full, color.full); +} + +/** + * @tc.name: UIChartDataSerialHidePoint_001 + * @tc.desc: Verify HidePoint function, equal. + * @tc.type: FUNC + * @tc.require: AR000EEMQ8 + */ +HWTEST_F(UIChartDataSerialTest, UIChartDataSerialHidePoint_001, TestSize.Level0) +{ + if (chartDataSerial_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + const uint16_t index = 3; + const uint16_t count = 5; + chartDataSerial_->HidePoint(index, count); + EXPECT_EQ(chartDataSerial_->GetHideIndex(), index); + EXPECT_EQ(chartDataSerial_->GetHideCount(), count); +} + +/** + * @tc.name: UIChartDataSerialSetHeadPointStyle_001 + * @tc.desc: Verify SetHeadPointStyle function, equal. + * @tc.type: FUNC + * @tc.require: AR000EEMQ8 + */ +HWTEST_F(UIChartDataSerialTest, UIChartDataSerialSetHeadPointStyle_001, TestSize.Level0) +{ + if (chartDataSerial_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + UIChartDataSerial::PointStyle pointStyle; + InitPointStyle(pointStyle); + + chartDataSerial_->SetHeadPointStyle(pointStyle); + UIChartDataSerial::PointStyle pointStyle1 = chartDataSerial_->GetHeadPointStyle(); + EXPECT_EQ(pointStyle1.fillColor.full, pointStyle.fillColor.full); + EXPECT_EQ(pointStyle1.strokeColor.full, pointStyle.strokeColor.full); + EXPECT_EQ(pointStyle1.strokeWidth, pointStyle.strokeWidth); + EXPECT_EQ(pointStyle1.radius, pointStyle.radius); +} + +/** + * @tc.name: UIChartDataSerialSetTopPointStyle_001 + * @tc.desc: Verify SetTopPointStyle function, equal. + * @tc.type: FUNC + * @tc.require: AR000EEMQ8 + */ +HWTEST_F(UIChartDataSerialTest, UIChartDataSerialSetTopPointStyle_001, TestSize.Level0) +{ + if (chartDataSerial_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + UIChartDataSerial::PointStyle pointStyle; + InitPointStyle(pointStyle); + + chartDataSerial_->SetTopPointStyle(pointStyle); + UIChartDataSerial::PointStyle pointStyle1 = chartDataSerial_->GetTopPointStyle(); + EXPECT_EQ(pointStyle1.fillColor.full, pointStyle.fillColor.full); + EXPECT_EQ(pointStyle1.strokeColor.full, pointStyle.strokeColor.full); + EXPECT_EQ(pointStyle1.strokeWidth, pointStyle.strokeWidth); + EXPECT_EQ(pointStyle1.radius, pointStyle.radius); +} + +/** + * @tc.name: UIChartDataSerialSetBottomPointStyle_001 + * @tc.desc: Verify SetBottomPointStyle function, equal. + * @tc.type: FUNC + * @tc.require: AR000EEMQ8 + */ +HWTEST_F(UIChartDataSerialTest, UIChartDataSerialSetBottomPointStyle_001, TestSize.Level0) +{ + if (chartDataSerial_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + UIChartDataSerial::PointStyle pointStyle; + InitPointStyle(pointStyle); + + chartDataSerial_->SetBottomPointStyle(pointStyle); + UIChartDataSerial::PointStyle pointStyle1 = chartDataSerial_->GetBottomPointStyle(); + EXPECT_EQ(pointStyle1.fillColor.full, pointStyle.fillColor.full); + EXPECT_EQ(pointStyle1.strokeColor.full, pointStyle.strokeColor.full); + EXPECT_EQ(pointStyle1.strokeWidth, pointStyle.strokeWidth); + EXPECT_EQ(pointStyle1.radius, pointStyle.radius); +} + +/** + * @tc.name: UIChartAddDataSerial_001 + * @tc.desc: Verify AddDataSerial function, equal. + * @tc.type: FUNC + * @tc.require: AR000EEMQ8 + */ +HWTEST_F(UIChartDataSerialTest, UIChartAddDataSerial_001, TestSize.Level0) +{ + if (chart_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + bool ret = chart_->AddDataSerial(nullptr); + EXPECT_EQ(ret, false); + ret = chart_->AddDataSerial(chartDataSerial_); + EXPECT_EQ(ret, true); + ret = chart_->AddDataSerial(chartDataSerial_); + EXPECT_EQ(ret, false); +} + +/** + * @tc.name: UIChartDeleteDataSerial_001 + * @tc.desc: Verify DeleteDataSerial function, equal. + * @tc.type: FUNC + * @tc.require: AR000EEMQ8 + */ +HWTEST_F(UIChartDataSerialTest, UIChartDeleteDataSerial_001, TestSize.Level0) +{ + if (chart_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + bool ret = chart_->DeleteDataSerial(nullptr); + EXPECT_EQ(ret, false); + ret = chart_->DeleteDataSerial(chartDataSerial_); + EXPECT_EQ(ret, false); + ret = chart_->AddDataSerial(chartDataSerial_); + EXPECT_EQ(ret, true); + ret = chart_->DeleteDataSerial(chartDataSerial_); + EXPECT_EQ(ret, true); +} + +/** + * @tc.name: UIChartClearDataSerial_001 + * @tc.desc: Verify ClearDataSerial function, equal. + * @tc.type: FUNC + * @tc.require: AR000EEMQ8 + */ +HWTEST_F(UIChartDataSerialTest, UIChartClearDataSerial_001, TestSize.Level0) +{ + if (chart_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + bool ret = chart_->AddDataSerial(chartDataSerial_); + EXPECT_EQ(ret, true); + chart_->ClearDataSerial(); + ret = chart_->DeleteDataSerial(chartDataSerial_); + EXPECT_EQ(ret, false); +} +} \ No newline at end of file diff --git a/test/unittest/components/ui_checkbox_unit_test.cpp b/test/unittest/components/ui_checkbox_unit_test.cpp new file mode 100755 index 0000000..9b4b4bc --- /dev/null +++ b/test/unittest/components/ui_checkbox_unit_test.cpp @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "components/ui_checkbox.h" + +#include +#include + +using namespace testing::ext; + +namespace OHOS { +class UICheckBoxTest : public testing::Test { +public: + static void SetUpTestCase(); + static void TearDownTestCase(); + static UICheckBox* checkBox_; +}; + +UICheckBox* UICheckBoxTest::checkBox_ = nullptr; + +void UICheckBoxTest::SetUpTestCase() +{ + if (checkBox_ == nullptr) { + checkBox_ = new UICheckBox(); + } +} + +void UICheckBoxTest::TearDownTestCase() +{ + if (checkBox_ != nullptr) { + delete checkBox_; + checkBox_ = nullptr; + } +} + +/** + * @tc.name: UICheckBoxGetViewType_001 + * @tc.desc: Verify SetState function, equal. + * @tc.type: FUNC + * @tc.require: AR000DSMQC + */ +HWTEST_F(UICheckBoxTest, UICheckBoxGetViewType_001, TestSize.Level0) +{ + if (checkBox_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + EXPECT_EQ(checkBox_->GetViewType(), UI_CHECK_BOX); +} + +/** + * @tc.name: UICheckBoxOnClickEvent_001 + * @tc.desc: Verify OnClickEvent function, equal. + * @tc.type: FUNC + * @tc.require: AR000EEMQ8 + */ +HWTEST_F(UICheckBoxTest, UICheckBoxOnClickEvent_001, TestSize.Level0) +{ + if (checkBox_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + ClickEvent event({0, 0}); + checkBox_->OnClickEvent(event); + EXPECT_EQ(checkBox_->GetState(), UICheckBox::SELECTED); +} + +/** + * @tc.name: UICheckBoxSetState_001 + * @tc.desc: Verify SetState function, equal. + * @tc.type: FUNC + * @tc.require: AR000EEMQ8 + */ +HWTEST_F(UICheckBoxTest, UICheckBoxSetState_001, TestSize.Level0) +{ + if (checkBox_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + checkBox_->SetState(UICheckBox::UICheckBoxState::SELECTED); + EXPECT_EQ(checkBox_->GetState(), UICheckBox::UICheckBoxState::SELECTED); + checkBox_->SetState(UICheckBox::UICheckBoxState::UNSELECTED); + EXPECT_EQ(checkBox_->GetState(), UICheckBox::UICheckBoxState::UNSELECTED); +} +} // namespace OHOS \ No newline at end of file diff --git a/test/unittest/components/ui_circle_progress_unit_test.cpp b/test/unittest/components/ui_circle_progress_unit_test.cpp new file mode 100755 index 0000000..977c31a --- /dev/null +++ b/test/unittest/components/ui_circle_progress_unit_test.cpp @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "components/ui_circle_progress.h" + +#include +#include + +using namespace testing::ext; +namespace OHOS { +namespace { + constexpr uint16_t MAX_ANGLE_VALUE = 360; + constexpr uint16_t MIN_ANGLE_VALUE = 0; +} +class UICircleProgressTest : public testing::Test { +public: + static void SetUpTestCase(); + static void TearDownTestCase(); + static UICircleProgress* circleProgress_; +}; + +UICircleProgress* UICircleProgressTest::circleProgress_ = nullptr; + +void UICircleProgressTest::SetUpTestCase() +{ + if (circleProgress_ == nullptr) { + circleProgress_ = new UICircleProgress(); + } +} + +void UICircleProgressTest::TearDownTestCase() +{ + if (circleProgress_ != nullptr) { + delete circleProgress_; + circleProgress_ = nullptr; + } +} + +/** + * @tc.name: UICircleProgressGetViewType_001 + * @tc.desc: Verify GetViewType function, equal. + * @tc.type: FUNC + * @tc.require: AR000DSMQG + */ +HWTEST_F(UICircleProgressTest, UICircleProgressGetViewType_001, TestSize.Level0) +{ + if (circleProgress_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + EXPECT_EQ(circleProgress_->GetViewType(), UI_CIRCLE_PROGRESS); +} + +/** + * @tc.name: UICircleProgressSetRadius_001 + * @tc.desc: Verify SetRadius function, equal. + * @tc.type: FUNC + * @tc.require: AR000DSMQG + */ +HWTEST_F(UICircleProgressTest, UICircleProgressSetRadius_001, TestSize.Level0) +{ + if (circleProgress_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + const uint16_t radius = 1; + + circleProgress_->SetRadius(radius); + EXPECT_EQ(circleProgress_->GetRadius(), radius); +} + +/** + * @tc.name: UICircleProgressSetCenterPosition_001 + * @tc.desc: Verify SetCenterPosition function, equal. + * @tc.type: FUNC + * @tc.require: AR000DSMQG + */ +HWTEST_F(UICircleProgressTest, UICircleProgressSetCenterPosition_001, TestSize.Level0) +{ + if (circleProgress_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + const int16_t presetLength = 100; + const int16_t centerX = 50; + const int16_t centerY = 50; + + circleProgress_->Resize(presetLength, presetLength); + circleProgress_->SetCenterPosition(centerX, centerY); + EXPECT_EQ(circleProgress_->GetCenterPosition().x, centerX); + EXPECT_EQ(circleProgress_->GetCenterPosition().y, centerY); +} + +/** + * @tc.name: UICircleProgressSetLineColor_001 + * @tc.desc: Verify SetLineColor function, equal. + * @tc.type: FUNC + * @tc.require: AR000DSMQG + */ +HWTEST_F(UICircleProgressTest, UICircleProgressSetLineColor_001, TestSize.Level0) +{ + if (circleProgress_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + circleProgress_->SetLineColor(Color::Red()); + EXPECT_EQ(circleProgress_->GetForegroundStyle(STYLE_LINE_COLOR), Color::Red().full); +} + +/** + * @tc.name: UICircleProgressSetAngle_001 + * @tc.desc: Verify SetAngle function, equal. + * @tc.type: FUNC + * @tc.require: AR000DSMQG + */ +HWTEST_F(UICircleProgressTest, UICircleProgressSetStartAngle_001, TestSize.Level0) +{ + if (circleProgress_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + const int16_t startAngle = 0; + const int16_t endAngle = 90; + + EXPECT_EQ(circleProgress_->GetStartAngle(), MIN_ANGLE_VALUE); + circleProgress_->SetStartAngle(startAngle); + EXPECT_EQ(circleProgress_->GetStartAngle(), startAngle); + + EXPECT_EQ(circleProgress_->GetEndAngle(), MAX_ANGLE_VALUE); + circleProgress_->SetEndAngle(endAngle); + EXPECT_EQ(circleProgress_->GetEndAngle(), endAngle); +} +} // namespace OHOS \ No newline at end of file diff --git a/test/unittest/components/ui_dialog_unit_test.cpp b/test/unittest/components/ui_dialog_unit_test.cpp new file mode 100755 index 0000000..06caf4b --- /dev/null +++ b/test/unittest/components/ui_dialog_unit_test.cpp @@ -0,0 +1,228 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "components/root_view.h" +#include "components/ui_dialog.h" + +#include +#include + +#if ENABLE_WINDOW +#if ENABLE_DEBUG +using namespace testing::ext; +namespace OHOS { +namespace { + const int16_t POS_X = 50; + const int16_t POS_Y = 100; + const uint16_t WIDTH = 100; + const uint16_t HEIGHT = 100; +} + +class UIDialogTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + static UIDialog* dialog_; + void SetUp(void); + void TearDown(void); +}; + +UIDialog* UIDialogTest::dialog_ = nullptr; +UIView::OnClickListener* listener_ = nullptr; + +void UIDialogTest::SetUpTestCase(void) +{ + listener_ = new UIView::OnClickListener(); +} + +void UIDialogTest::SetUp(void) +{ + if (dialog_ != nullptr) { + delete dialog_; + } + dialog_ = new UIDialog(); +} + + +void UIDialogTest::TearDown(void) +{ + if (dialog_ != nullptr) { + delete dialog_; + dialog_ = nullptr; + } +} + +void UIDialogTest::TearDownTestCase(void) +{ + if (listener_ != nullptr) { + delete listener_; + listener_ = nullptr; + } +} + +/** + * @tc.name: UIDialogSetTitle_001 + * @tc.desc: Verify SetTitle function, equal. + * @tc.type: FUNC + * @tc.require: AR000F4E5F + */ +HWTEST_F(UIDialogTest, UIDialogSetTitle_001, TestSize.Level0) +{ + const char* title1 = "title1"; + dialog_->SetTitle(title1); + EXPECT_EQ(dialog_->GetTitle(), title1); + const char* title2 = "title2"; + dialog_->SetTitle(title2); + EXPECT_EQ(dialog_->GetTitle(), title2); +} + +/** + * @tc.name: UIDialogSetTitle_002 + * @tc.desc: Verify SetTitle function, equal. + * @tc.type: FUNC + * @tc.require: AR000F4E5F + */ +HWTEST_F(UIDialogTest, UIDialogSetTitle_002, TestSize.Level0) +{ + dialog_->SetTitle(nullptr); + EXPECT_EQ(dialog_->GetTitle(), nullptr); + const char* title = "title"; + dialog_->SetTitle(title); + dialog_->SetTitle(nullptr); + EXPECT_EQ(dialog_->GetTitle(), title); +} + +/** + * @tc.name: UIDialogSetText_001 + * @tc.desc: Verify SetText function, equal. + * @tc.type: FUNC + * @tc.require: AR000F4E5F + */ +HWTEST_F(UIDialogTest, UIDialogSetText_001, TestSize.Level0) +{ + const char* text1 = "text1"; + dialog_->SetText(text1); + EXPECT_EQ(dialog_->GetText(), text1); + const char* text2 = "text2"; + dialog_->SetText(text2); + EXPECT_EQ(dialog_->GetText(), text2); +} + +/** + * @tc.name: UIDialogSetText_002 + * @tc.desc: Verify SetText function, equal. + * @tc.type: FUNC + * @tc.require: AR000F4E5F + */ +HWTEST_F(UIDialogTest, UIDialogSetText_002, TestSize.Level0) +{ + dialog_->SetText(nullptr); + EXPECT_EQ(dialog_->GetText(), nullptr); + const char* text = "text"; + dialog_->SetText(text); + dialog_->SetText(nullptr); + EXPECT_EQ(dialog_->GetText(), text); +} + +/** + * @tc.name: UIDialogSetButton_001 + * @tc.desc: Verify SetButton function, equal. + * @tc.type: FUNC + * @tc.require: AR000F4E5F + */ +HWTEST_F(UIDialogTest, UIDialogSetButton_001, TestSize.Level0) +{ + const char* buttonText = "button"; + dialog_->SetButton(UIDialog::DialogButtonType::BUTTON_LEFT, buttonText, listener_); + const char* buttonText0 = dialog_->GetButtonText(UIDialog::DialogButtonType::BUTTON_LEFT); + ASSERT_TRUE(buttonText0); + if (strcmp(buttonText0, buttonText) != 0) { + EXPECT_EQ(1, 0); + } + EXPECT_EQ(dialog_->GetButtonListener(UIDialog::DialogButtonType::BUTTON_LEFT), listener_); +} + +/** + * @tc.name: UIDialogSetButtonColor_001 + * @tc.desc: Verify SetButtonColor function, equal. + * @tc.type: FUNC + * @tc.require: AR000F4E5F + */ +HWTEST_F(UIDialogTest, UIDialogSetButtonColor_001, TestSize.Level0) +{ + dialog_->SetButton(UIDialog::DialogButtonType::BUTTON_LEFT, "button", listener_); + ColorType color = Color::Red(); + dialog_->SetButtonColor(UIDialog::DialogButtonType::BUTTON_LEFT, color); + EXPECT_EQ(dialog_->GetButtonColor(UIDialog::DialogButtonType::BUTTON_LEFT).full, color.full); +} + +/** + * @tc.name: UIDialogSetOnCancelListener_001 + * @tc.desc: Verify SetOnCancelListener function, equal. + * @tc.type: FUNC + * @tc.require: AR000F4E5F + */ +HWTEST_F(UIDialogTest, UIDialogSetOnCancelListener_001, TestSize.Level0) +{ + dialog_->SetOnCancelListener(nullptr); + EXPECT_EQ(dialog_->GetOnCancelListener(), nullptr); + dialog_->SetOnCancelListener(listener_); + EXPECT_EQ(dialog_->GetOnCancelListener(), listener_); +} + +/** + * @tc.name: UIDialogEnableAutoCancel_001 + * @tc.desc: Verify EnableAutoCancel function, equal. + * @tc.type: FUNC + * @tc.require: AR000F4E5F + */ +HWTEST_F(UIDialogTest, UIDialogEnableAutoCancel_001, TestSize.Level0) +{ + dialog_->EnableAutoCancel(true); + EXPECT_EQ(dialog_->GetEnableAutoCancel(), true); + dialog_->EnableAutoCancel(false); + EXPECT_EQ(dialog_->GetEnableAutoCancel(), false); +} + +/** + * @tc.name: UIDialog_001 + * @tc.desc: Verify UIDialog function, equal. + * @tc.type: FUNC + * @tc.require: SR000F3PED + */ +HWTEST_F(UIDialogTest, UIDialog_001, TestSize.Level0) +{ + const char* title = "title"; + dialog_->SetTitle(title); + EXPECT_EQ(dialog_->GetTitle(), title); + const char* text = "text"; + dialog_->SetText(text); + EXPECT_EQ(dialog_->GetText(), text); + const char* buttonText = "button"; + dialog_->SetButton(UIDialog::DialogButtonType::BUTTON_LEFT, buttonText, listener_); + const char* buttonText0 = dialog_->GetButtonText(UIDialog::DialogButtonType::BUTTON_LEFT); + ASSERT_TRUE(buttonText0); + if (strcmp(buttonText0, buttonText) != 0) { + EXPECT_EQ(1, 0); + } + EXPECT_EQ(dialog_->GetButtonListener(UIDialog::DialogButtonType::BUTTON_LEFT), listener_); + dialog_->SetOnCancelListener(listener_); + EXPECT_EQ(dialog_->GetOnCancelListener(), listener_); + dialog_->EnableAutoCancel(true); + EXPECT_EQ(dialog_->GetEnableAutoCancel(), true); +} +} // namespace OHOS +#endif // ENABLE_DEBUG +#endif // ENABLE_WINDOW \ No newline at end of file diff --git a/test/unittest/components/ui_digital_clock_unit_test.cpp b/test/unittest/components/ui_digital_clock_unit_test.cpp new file mode 100644 index 0000000..0a13153 --- /dev/null +++ b/test/unittest/components/ui_digital_clock_unit_test.cpp @@ -0,0 +1,177 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "components/ui_digital_clock.h" +#include +#include + +using namespace testing::ext; + +namespace OHOS { +namespace { + const uint8_t CURRENT_HOUR = 14; + const uint8_t CURRENT_MINUTE = 40; + const uint8_t CURRENT_SECOND = 30; + const uint8_t HALF_DAY_IN_HOUR = 12; +} + +class UIDigitalClockTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + static UIDigitalClock* digitalClock_; +}; + +UIDigitalClock* UIDigitalClockTest::digitalClock_ = nullptr; + +void UIDigitalClockTest::SetUpTestCase(void) +{ + if (digitalClock_ == nullptr) { + digitalClock_ = new UIDigitalClock(); + } +} + +void UIDigitalClockTest::TearDownTestCase(void) +{ + if (digitalClock_ != nullptr) { + delete digitalClock_; + digitalClock_ = nullptr; + } +} + +/** + * @tc.name: UIDigitalClockGetViewType_001 + * @tc.desc: Verify GetViewType function, equal. + * @tc.type: FUNC + * @tc.require: AR000EEMQ4 + */ +HWTEST_F(UIDigitalClockTest, UIDigitalClockGetViewType_001, TestSize.Level1) +{ + if (digitalClock_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + EXPECT_EQ(digitalClock_->GetViewType(), UI_DIGITAL_CLOCK); +} + +/** + * @tc.name: UIDigitalClockSetFontId_001 + * @tc.desc: Verify SetFontId function, equal. + * @tc.type: FUNC + * @tc.require: AR000EEMQ4 + */ +HWTEST_F(UIDigitalClockTest, UIDigitalClockSetFontId_001, TestSize.Level1) +{ + if (digitalClock_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + const uint8_t fontId = 10; + digitalClock_->SetFontId(fontId); + EXPECT_EQ(digitalClock_->GetStyle(STYLE_TEXT_FONT), fontId); +} + +/** + * @tc.name: UIDigitalClockSetDisplayMode_001 + * @tc.desc: Verify SetDisplayMode function, equal. + * @tc.type: FUNC + * @tc.require: AR000EEMQ4 + */ +HWTEST_F(UIDigitalClockTest, UIDigitalClockSetDisplayMode_001, TestSize.Level0) +{ + if (digitalClock_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + digitalClock_->SetDisplayMode(UIDigitalClock::DisplayMode::DISPLAY_12_HOUR_NO_SECONDS); + EXPECT_EQ(digitalClock_->GetDisplayMode(), UIDigitalClock::DisplayMode::DISPLAY_12_HOUR_NO_SECONDS); + digitalClock_->SetDisplayMode(UIDigitalClock::DisplayMode::DISPLAY_24_HOUR_NO_SECONDS); + EXPECT_EQ(digitalClock_->GetDisplayMode(), UIDigitalClock::DisplayMode::DISPLAY_24_HOUR_NO_SECONDS); + digitalClock_->SetDisplayMode(UIDigitalClock::DisplayMode::DISPLAY_12_HOUR); + EXPECT_EQ(digitalClock_->GetDisplayMode(), UIDigitalClock::DisplayMode::DISPLAY_12_HOUR); + digitalClock_->SetDisplayMode(UIDigitalClock::DisplayMode::DISPLAY_24_HOUR); + EXPECT_EQ(digitalClock_->GetDisplayMode(), UIDigitalClock::DisplayMode::DISPLAY_24_HOUR); +} + +/** + * @tc.name: UIDigitalClockSetOpacity_001 + * @tc.desc: Verify SetOpacity function, equal. + * @tc.type: FUNC + * @tc.require: AR000EEMQ4 + */ +HWTEST_F(UIDigitalClockTest, UIDigitalClockSetOpacity_001, TestSize.Level0) +{ + if (digitalClock_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + digitalClock_->SetOpacity(OPA_OPAQUE); + EXPECT_EQ(digitalClock_->GetOpacity(), OPA_OPAQUE); +} + +/** + * @tc.name: UIDigitalClockSetTime24Hour_001 + * @tc.desc: Verify SetTime24Hour function, equal. + * @tc.type: FUNC + * @tc.require: AR000EEMQ4 + */ +HWTEST_F(UIDigitalClockTest, UIDigitalClockSetTime24Hour_001, TestSize.Level0) +{ + if (digitalClock_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + digitalClock_->SetTime24Hour(CURRENT_HOUR, CURRENT_MINUTE, CURRENT_SECOND); + EXPECT_EQ(digitalClock_->GetCurrentHour(), CURRENT_HOUR); + EXPECT_EQ(digitalClock_->GetCurrentMinute(), CURRENT_MINUTE); + EXPECT_EQ(digitalClock_->GetCurrentSecond(), CURRENT_SECOND); +} + +/** + * @tc.name: UIDigitalClockSetTime12Hour_001 + * @tc.desc: Verify SetTime12Hour function, equal. + * @tc.type: FUNC + * @tc.require: AR000EEMQ4 + */ +HWTEST_F(UIDigitalClockTest, UIDigitalClockSetTime12Hour_001, TestSize.Level0) +{ + if (digitalClock_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + digitalClock_->SetTime12Hour(CURRENT_HOUR, CURRENT_MINUTE, CURRENT_SECOND, true); + EXPECT_EQ(digitalClock_->GetCurrentHour(), CURRENT_HOUR - HALF_DAY_IN_HOUR); + EXPECT_EQ(digitalClock_->GetCurrentMinute(), CURRENT_MINUTE); + EXPECT_EQ(digitalClock_->GetCurrentSecond(), CURRENT_SECOND); +} + +/** + * @tc.name: UIDigitalClockSetTime12Hour_002 + * @tc.desc: Verify SetTime12Hour function, equal. + * @tc.type: FUNC + * @tc.require: AR000EEMQ4 + */ +HWTEST_F(UIDigitalClockTest, UIDigitalClockSetTime12Hour_002, TestSize.Level0) +{ + if (digitalClock_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + digitalClock_->SetTime12Hour(CURRENT_HOUR, CURRENT_MINUTE, CURRENT_SECOND, false); + EXPECT_EQ(digitalClock_->GetCurrentHour(), CURRENT_HOUR); + EXPECT_EQ(digitalClock_->GetCurrentMinute(), CURRENT_MINUTE); + EXPECT_EQ(digitalClock_->GetCurrentSecond(), CURRENT_SECOND); +} +} \ No newline at end of file diff --git a/test/unittest/components/ui_image_animator_unit_test.cpp b/test/unittest/components/ui_image_animator_unit_test.cpp new file mode 100644 index 0000000..f0769f0 --- /dev/null +++ b/test/unittest/components/ui_image_animator_unit_test.cpp @@ -0,0 +1,367 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "components/ui_image_animator.h" + +#include +#include +#include "file.h" +#include "test_resource_config.h" + +using namespace testing::ext; +namespace OHOS { +namespace { + const Point INIT_POS = { 50, 50 }; + const int16_t INIT_WIDTH = 94; + const int16_t INIT_HEIGHT = 94; + const uint8_t IMAGE_SIZE = 3; +} + +class UIImageAnimatorViewTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + static UIImageAnimatorView* imageAnimator_; +}; + +UIImageAnimatorView* UIImageAnimatorViewTest::imageAnimator_ = nullptr; + +void UIImageAnimatorViewTest::SetUpTestCase(void) +{ + if (imageAnimator_ == nullptr) { + imageAnimator_ = new UIImageAnimatorView(); + } +} + +void UIImageAnimatorViewTest::TearDownTestCase(void) +{ + if (imageAnimator_ != nullptr) { + delete imageAnimator_; + imageAnimator_ = nullptr; + } +} + +static ImageAnimatorInfo g_imageAnimatorInfo[IMAGE_SIZE] = { + { BLUE_RGB888_IMAGE_PATH, INIT_POS, INIT_WIDTH, INIT_HEIGHT, IMG_SRC_FILE_PATH }, + { BLUE_ARGB8888_IMAGE_PATH, INIT_POS, INIT_WIDTH, INIT_HEIGHT, IMG_SRC_FILE_PATH }, + { BLUE_RGB565_IMAGE_PATH, INIT_POS, INIT_WIDTH, INIT_HEIGHT, IMG_SRC_FILE_PATH }, +}; + +/** + * @tc.name: UIImageAnimatorViewGetViewType_001 + * @tc.desc: Verify GetViewType function, equal. + * @tc.type: FUNC + * @tc.require: AR000DSMQL + */ +HWTEST_F(UIImageAnimatorViewTest, UIImageAnimatorViewGetViewType_001, TestSize.Level0) +{ + if (imageAnimator_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + EXPECT_EQ(imageAnimator_->GetViewType(), UI_IMAGE_ANIMATOR_VIEW); +} + +/** + * @tc.name: UIImageAnimatorViewSetTimeOfPause_001 + * @tc.desc: Verify SetTimeOfPause function, equal. + * @tc.type: FUNC + * @tc.require: AR000DSMQL + */ +HWTEST_F(UIImageAnimatorViewTest, UIImageAnimatorViewSetTimeOfPause_001, TestSize.Level0) +{ + if (imageAnimator_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + uint16_t timeOfPause = 1; + + imageAnimator_->SetTimeOfPause(timeOfPause); + EXPECT_EQ(imageAnimator_->GetTimeOfPause(), timeOfPause); +} + +/** + * @tc.name: UIImageAnimatorViewSetTimeOfUpdate_001 + * @tc.desc: Verify SetTimeOfUpdate function, equal. + * @tc.type: FUNC + * @tc.require: AR000DSMQL + */ +HWTEST_F(UIImageAnimatorViewTest, UIImageAnimatorViewSetTimeOfUpdate_001, TestSize.Level0) +{ + if (imageAnimator_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + const uint16_t animatorTime = 300; + + imageAnimator_->SetTimeOfUpdate(animatorTime); + EXPECT_EQ(imageAnimator_->GetTimeOfUpdate(), animatorTime); +} + +/** + * @tc.name: UIImageAnimatorViewSetImageAnimatorSrc_001 + * @tc.desc: Verify SetImageAnimatorSrc function, equal. + * @tc.type: FUNC + * @tc.require: AR000DSMQL + */ +HWTEST_F(UIImageAnimatorViewTest, UIImageAnimatorViewSetImageAnimatorSrc_001, TestSize.Level0) +{ + if (imageAnimator_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + const uint8_t imageSize = IMAGE_SIZE; + + imageAnimator_->SetImageAnimatorSrc(g_imageAnimatorInfo, imageSize); + EXPECT_EQ(imageAnimator_->GetImageAnimatorImageNum(), imageSize); +} + +/** + * @tc.name: UIImageAnimatorViewSetImageAnimatorSrc_002 + * @tc.desc: Verify SetImageAnimatorSrc function, equal. + * @tc.type: FUNC + * @tc.require: AR000DSMPV + */ +HWTEST_F(UIImageAnimatorViewTest, UIImageAnimatorViewSetImageAnimatorSrc_002, TestSize.Level0) +{ + if (imageAnimator_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + ImageAnimatorInfo* info = &g_imageAnimatorInfo[0]; + imageAnimator_->SetImageAnimatorSrc(g_imageAnimatorInfo, IMAGE_SIZE); + + EXPECT_EQ(imageAnimator_->GetImageAnimatorSrc(), info); +} + +/** + * @tc.name: UIImageAnimatorViewSetSizeFixed_001 + * @tc.desc: Verify SetSizeFixed function, equal. + * @tc.type: FUNC + * @tc.require: AR000DSMPV + */ +HWTEST_F(UIImageAnimatorViewTest, UIImageAnimatorViewSetSizeFixed_001, TestSize.Level0) +{ + if (imageAnimator_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + bool fixed = true; + + imageAnimator_->SetSizeFixed(fixed); + EXPECT_EQ(imageAnimator_->IsSizeFixed(), fixed); +} + +/** + * @tc.name: UIImageAnimatorViewSetRepeat_001 + * @tc.desc: Verify SetRepeat function, equal. + * @tc.type: FUNC + * @tc.require: AR000DSMPV + */ +HWTEST_F(UIImageAnimatorViewTest, UIImageAnimatorViewSetRepeat_001, TestSize.Level0) +{ + if (imageAnimator_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + bool repeat = true; + + imageAnimator_->SetRepeat(repeat); + EXPECT_EQ(imageAnimator_->IsRepeat(), repeat); +} + +/** + * @tc.name: UIImageAnimatorViewSetReverse_001 + * @tc.desc: Verify SetReverse function, equal. + * @tc.type: FUNC + * @tc.require: AR000DSMPV + */ +HWTEST_F(UIImageAnimatorViewTest, UIImageAnimatorViewSetReverse_001, TestSize.Level0) +{ + if (imageAnimator_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + bool reverse = true; + + imageAnimator_->SetReverse(reverse); + EXPECT_EQ(imageAnimator_->IsReverse(), reverse); +} + +/** + * @tc.name: UIImageAnimatorViewSetStartPosition_001 + * @tc.desc: Verify SetStartPosition function, equal. + * @tc.type: FUNC + * @tc.require: AR000DSMPV + */ +HWTEST_F(UIImageAnimatorViewTest, UIImageAnimatorViewSetStartPosition_001, TestSize.Level0) +{ + if (imageAnimator_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + uint8_t state = Animator::STOP; + + EXPECT_EQ(imageAnimator_->GetState(), state); +} + +/** + * @tc.name: UIImageAnimatorViewStart_010 + * @tc.desc: Verify Start function, equal. + * @tc.type: FUNC + * @tc.require: AR000DSMPV + */ +HWTEST_F(UIImageAnimatorViewTest, UIImageAnimatorViewStart_001, TestSize.Level0) +{ + if (imageAnimator_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + imageAnimator_->Start(); + EXPECT_EQ(imageAnimator_->GetState(), Animator::START); +} + +/** + * @tc.name: UIImageAnimatorViewStop_001 + * @tc.desc: Verify Stop function, equal. + * @tc.type: FUNC + * @tc.require: AR000DSMPV + */ +HWTEST_F(UIImageAnimatorViewTest, UIImageAnimatorViewStop_001, TestSize.Level0) +{ + if (imageAnimator_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + imageAnimator_->Stop(); + EXPECT_EQ(imageAnimator_->GetState(), Animator::STOP); +} + +/** + * @tc.name: UIImageAnimatorViewPause_001 + * @tc.desc: Verify Pause function, equal. + * @tc.type: FUNC + * @tc.require: AR000DSMPV + */ +HWTEST_F(UIImageAnimatorViewTest, UIImageAnimatorViewPause_001, TestSize.Level0) +{ + if (imageAnimator_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + imageAnimator_->Pause(); + EXPECT_EQ(imageAnimator_->GetState(), Animator::PAUSE); +} + +/** + * @tc.name: UIImageAnimatorViewResume_001 + * @tc.desc: Verify Resume function, equal. + * @tc.type: FUNC + * @tc.require: AR000DSMPV + */ +HWTEST_F(UIImageAnimatorViewTest, UIImageAnimatorViewResume_001, TestSize.Level0) +{ + if (imageAnimator_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + imageAnimator_->Resume(); + EXPECT_EQ(imageAnimator_->GetState(), Animator::START); +} + +/** + * @tc.name: UIImageAnimatorViewSetFillMode_001 + * @tc.desc: Verify SetFillMode function, equal. + * @tc.type: FUNC + * @tc.require: SR000F3PEF + */ +HWTEST_F(UIImageAnimatorViewTest, UIImageAnimatorViewSetFillMode_001, TestSize.Level0) +{ + if (imageAnimator_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + + imageAnimator_->SetImageAnimatorSrc(g_imageAnimatorInfo, IMAGE_SIZE); + imageAnimator_->SetFillMode(true); + imageAnimator_->SetReverse(false); + imageAnimator_->Start(); + imageAnimator_->Stop(); + EXPECT_STREQ(imageAnimator_->GetPath(), g_imageAnimatorInfo[2].imagePath); // 2: the last image +} + +/** + * @tc.name: UIImageAnimatorViewSetFillMode_002 + * @tc.desc: Verify SetFillMode function, equal. + * @tc.type: FUNC + * @tc.require: AR000F4E5J + */ +HWTEST_F(UIImageAnimatorViewTest, UIImageAnimatorViewSetFillMode_002, TestSize.Level0) +{ + if (imageAnimator_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + + imageAnimator_->SetImageAnimatorSrc(g_imageAnimatorInfo, IMAGE_SIZE); + imageAnimator_->SetFillMode(true); + imageAnimator_->SetReverse(true); + imageAnimator_->Start(); + imageAnimator_->Stop(); + EXPECT_STREQ(imageAnimator_->GetPath(), g_imageAnimatorInfo[0].imagePath); +} + +/** + * @tc.name: UIImageAnimatorViewSetFillMode_003 + * @tc.desc: Verify SetFillMode function, equal. + * @tc.type: FUNC + * @tc.require: AR000F4E5J + */ +HWTEST_F(UIImageAnimatorViewTest, UIImageAnimatorViewSetFillMode_003, TestSize.Level0) +{ + if (imageAnimator_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + + imageAnimator_->SetImageAnimatorSrc(g_imageAnimatorInfo, IMAGE_SIZE); + imageAnimator_->SetFillMode(false); + imageAnimator_->SetReverse(false); + imageAnimator_->Start(); + imageAnimator_->Stop(); + EXPECT_STREQ(imageAnimator_->GetPath(), g_imageAnimatorInfo[0].imagePath); +} + +/** + * @tc.name: UIImageAnimatorViewSetFillMode_004 + * @tc.desc: Verify SetFillMode function, equal. + * @tc.type: FUNC + * @tc.require: AR000F4E5J + */ +HWTEST_F(UIImageAnimatorViewTest, UIImageAnimatorViewSetFillMode_004, TestSize.Level0) +{ + if (imageAnimator_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + + imageAnimator_->SetImageAnimatorSrc(g_imageAnimatorInfo, IMAGE_SIZE); + imageAnimator_->SetFillMode(false); + imageAnimator_->SetReverse(true); + imageAnimator_->Start(); + imageAnimator_->Stop(); + EXPECT_STREQ(imageAnimator_->GetPath(), g_imageAnimatorInfo[2].imagePath); // 2: the last image +} +} // namespace OHOS diff --git a/test/unittest/components/ui_image_unit_test.cpp b/test/unittest/components/ui_image_unit_test.cpp new file mode 100644 index 0000000..3e074a0 --- /dev/null +++ b/test/unittest/components/ui_image_unit_test.cpp @@ -0,0 +1,409 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "components/ui_image_view.h" +#include +#include +#include "components/root_view.h" +#include "components/ui_view_group.h" +#include "test_resource_config.h" + +using namespace testing::ext; + +namespace OHOS { +class UIImageViewTest : public testing::Test { +public: + UIImageViewTest() : imageView_(nullptr) {} + ~UIImageViewTest() {} + static void SetUpTestCase(void) {} + static void TearDownTestCase(void) {} + void SetUp(void); + void TearDown(void); + UIImageView* imageView_; +}; + +void UIImageViewTest::SetUp(void) +{ + if (imageView_ == nullptr) { + imageView_ = new UIImageView(); + } +} + +void UIImageViewTest::TearDown(void) +{ + if (imageView_ != nullptr) { + delete imageView_; + imageView_ = nullptr; + } +} + +/** + * @tc.name: UIImageViewGetViewType_001 + * @tc.desc: Verify GetViewType function, equal. + * @tc.type: FUNC + * @tc.require: AR000DSMQ1 + */ +HWTEST_F(UIImageViewTest, UIImageViewGetViewType_001, TestSize.Level0) +{ + if (imageView_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + EXPECT_EQ(imageView_->GetViewType(), UI_IMAGE_VIEW); +} + +/** + * @tc.name: UIImageViewSetPosition_001 + * @tc.desc: Verify SetPosition function, equal. + * @tc.type: FUNC + * @tc.require: AR000DSMQ1 + */ +HWTEST_F(UIImageViewTest, UIImageViewSetPosition_001, TestSize.Level0) +{ + if (imageView_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + const int16_t initPosX = 10; + const int16_t initPosY = 10; + const int16_t initWidth = 100; + const int16_t initHeight = 150; + + imageView_->SetPosition(initPosX, initPosY); + imageView_->SetHeight(initWidth); + imageView_->SetWidth(initHeight); + + EXPECT_EQ(imageView_->GetX(), initPosX); + EXPECT_EQ(imageView_->GetY(), initPosY); + EXPECT_EQ(imageView_->GetHeight(), initWidth); + EXPECT_EQ(imageView_->GetWidth(), initHeight); + + imageView_->SetPosition(0, 0, 0, 0); + EXPECT_EQ(imageView_->GetX(), 0); + EXPECT_EQ(imageView_->GetY(), 0); + EXPECT_EQ(imageView_->GetWidth(), 0); + EXPECT_EQ(imageView_->GetHeight(), 0); +} + +#ifndef VERSION_LITE +/** + * @tc.name: UIImageViewSetSrc_001 + * @tc.desc: Verify SetSrc function, correct gif path, equal. + * @tc.type: FUNC + * @tc.require: SR000F3PEO + */ +HWTEST_F(UIImageViewTest, UIImageViewSetSrc_001, TestSize.Level0) +{ + if (imageView_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + const char* strPath1 = static_cast(GIF_IMAGE_PATH1); + imageView_->SetSrc(strPath1); + EXPECT_EQ(imageView_->GetPath(), nullptr); +} + +/** + * @tc.name: UIImageViewSetSrc_002 + * @tc.desc: Verify SetSrc function, error gif path, equal. + * @tc.type: FUNC + * @tc.require: AR000F3R70 + */ +HWTEST_F(UIImageViewTest, UIImageViewSetSrc_002, TestSize.Level0) +{ + if (imageView_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + const char* strPathError = static_cast(GIF_IMAGE_PATH_ERROR); + imageView_->SetSrc(strPathError); + EXPECT_EQ(imageView_->GetPath(), nullptr); +} + +/** + * @tc.name: UIImageViewSetSrc_003 + * @tc.desc: Verify SetSrc function, tif image format path, equal. + * @tc.type: FUNC + * @tc.require: AR000F3R70 + */ +HWTEST_F(UIImageViewTest, UIImageViewSetSrc_003, TestSize.Level0) +{ + if (imageView_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + const char* strPath = static_cast(TIF_IMAGE_PATH); + imageView_->SetSrc(strPath); + EXPECT_STREQ(imageView_->GetPath(), strPath); +} +#endif + +/** + * @tc.name: UIImageViewSetSrc_004 + * @tc.desc: Verify SetSrc function, equal. + * @tc.type: FUNC + * @tc.require: AR000DSMQ1 + */ +HWTEST_F(UIImageViewTest, UIImageViewSetSrc_004, TestSize.Level0) +{ + if (imageView_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + char* srcPath = nullptr; + imageView_->SetSrc(srcPath); + EXPECT_EQ(imageView_->GetPath(), srcPath); + const char* strPath2 = static_cast(BLUE_RGB888_IMAGE_PATH); + imageView_->SetSrc(strPath2); + EXPECT_STREQ(imageView_->GetPath(), strPath2); + ImageInfo* srcPath2 = nullptr; + imageView_->SetSrc(srcPath2); + EXPECT_EQ(imageView_->GetImageInfo(), srcPath2); +} + +/** + * @tc.name: UIImageViewSetAutoEnable_001 + * @tc.desc: Verify SetAutoEnable function, equal. + * @tc.type: FUNC + * @tc.require: AR000DSMQ1 + */ +HWTEST_F(UIImageViewTest, UIImageViewSetAutoEnable_001, TestSize.Level0) +{ + if (imageView_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + imageView_->SetAutoEnable(true); + EXPECT_EQ(imageView_->GetAutoEnable(), true); +} + +/** + * @tc.name: UIImageViewSetParent_001 + * @tc.desc: Verify SetParent function, equal. + * @tc.type: FUNC + * @tc.require: AR000DSMQ1 + */ +HWTEST_F(UIImageViewTest, UIImageViewSetParent_001, TestSize.Level0) +{ + if (imageView_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + UIView uiView; + imageView_->SetParent(nullptr); + EXPECT_EQ(imageView_->GetParent(), nullptr); + imageView_->SetParent(&uiView); + EXPECT_NE(imageView_->GetParent(), nullptr); +} + +/** + * @tc.name: UIImageViewSetNextSibling_001 + * @tc.desc: Verify SetNextSibling function, equal. + * @tc.type: FUNC + * @tc.require: AR000DSMQ1 + */ +HWTEST_F(UIImageViewTest, UIImageViewSetNextSibling_001, TestSize.Level0) +{ + if (imageView_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + UIView uiView; + imageView_->SetNextSibling(nullptr); + EXPECT_EQ(imageView_->GetNextSibling(), nullptr); + imageView_->SetNextSibling(&uiView); + EXPECT_NE(imageView_->GetNextSibling(), nullptr); +} + +/** + * @tc.name: UIImageViewSetVisible_001 + * @tc.desc: Verify SetVisible function, equal. + * @tc.type: FUNC + * @tc.require: AR000DSMQ1 + */ +HWTEST_F(UIImageViewTest, UIImageViewSetVisible_001, TestSize.Level0) +{ + if (imageView_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + imageView_->SetVisible(true); + EXPECT_EQ(imageView_->IsVisible(), true); + imageView_->SetVisible(false); + EXPECT_EQ(imageView_->IsVisible(), false); +} + +/** + * @tc.name: UIImageViewSetTouchable_001 + * @tc.desc: Verify SetTouchable function, equal. + * @tc.type: FUNC + * @tc.require: AR000DSMQ1 + */ +HWTEST_F(UIImageViewTest, UIImageViewSetTouchable_001, TestSize.Level0) +{ + if (imageView_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + imageView_->SetTouchable(true); + EXPECT_EQ(imageView_->IsTouchable(), true); + imageView_->SetTouchable(false); + EXPECT_EQ(imageView_->IsTouchable(), false); +} + +/** + * @tc.name: UIImageViewSetDraggable_001 + * @tc.desc: Verify SetDraggable function, equal. + * @tc.type: FUNC + * @tc.require: AR000DSMQ1 + */ +HWTEST_F(UIImageViewTest, UIImageViewSetDraggable_001, TestSize.Level0) +{ + if (imageView_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + imageView_->SetDraggable(true); + EXPECT_EQ(imageView_->IsDraggable(), true); + imageView_->SetDraggable(false); + EXPECT_EQ(imageView_->IsDraggable(), false); +} + +/** + * @tc.name: UIImageViewSetDragParentInstead_001 + * @tc.desc: Verify SetDragParentInstead function, equal. + * @tc.type: FUNC + * @tc.require: AR000DSMQ1 + */ +HWTEST_F(UIImageViewTest, UIImageViewSetDragParentInstead_001, TestSize.Level0) +{ + if (imageView_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + imageView_->SetDragParentInstead(true); + EXPECT_EQ(imageView_->IsDragParentInstead(), true); + imageView_->SetDragParentInstead(false); + EXPECT_EQ(imageView_->IsDragParentInstead(), false); +} + +/** + * @tc.name: UIImageViewResize_001 + * @tc.desc: Verify Resize function, equal. + * @tc.type: FUNC + * @tc.require: AR000DSMQ1 + */ +HWTEST_F(UIImageViewTest, UIImageViewResize_001, TestSize.Level0) +{ + if (imageView_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + const int16_t currPosX = 100; + const int16_t currPosY = 300; + + imageView_->Resize(currPosX, currPosY); + EXPECT_EQ(imageView_->GetWidth(), currPosX); + EXPECT_EQ(imageView_->GetHeight(), currPosY); +} + +/** + * @tc.name: UIImageViewSetListener_001 + * @tc.desc: Verify SetListener function, equal. + * @tc.type: FUNC + * @tc.require: AR000DSMQ1 + */ +HWTEST_F(UIImageViewTest, UIImageViewSetListener_001, TestSize.Level0) +{ + if (imageView_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + imageView_->SetOnDragListener(nullptr); + imageView_->SetOnClickListener(nullptr); + imageView_->SetOnLongPressListener(nullptr); + + EXPECT_EQ(imageView_->GetOnDragListener(), nullptr); + EXPECT_EQ(imageView_->GetOnClickListener(), nullptr); + EXPECT_EQ(imageView_->GetOnLongPressListener(), nullptr); +} + +/** + * @tc.name: UIImageViewSetViewId_001 + * @tc.desc: Verify SetViewId function, equal. + * @tc.type: FUNC + * @tc.require: AR000DSMQ1 + */ +HWTEST_F(UIImageViewTest, UIImageViewSetViewId_001, TestSize.Level0) +{ + if (imageView_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + imageView_->SetViewId(nullptr); + EXPECT_EQ(imageView_->GetViewId(), nullptr); +} + +/** + * @tc.name: UIImageViewSetViewIndex_001 + * @tc.desc: Verify SetViewIndex function, equal. + * @tc.type: FUNC + * @tc.require: AR000DSMQ1 + */ +HWTEST_F(UIImageViewTest, UIImageViewSetViewIndex_001, TestSize.Level0) +{ + if (imageView_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + const int16_t index = 101; + imageView_->SetViewIndex(index); + EXPECT_EQ(imageView_->GetViewIndex(), index); +} + +/** + * @tc.name: UIImageViewSetBlurLevel_001 + * @tc.desc: Verify SetBlurLevel function, equal. + * @tc.type: FUNC + * @tc.require: AR000DSMQ1 + */ +HWTEST_F(UIImageViewTest, UIImageViewSetBlurLevel_001, TestSize.Level0) +{ + if (imageView_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + BlurLevel level = LEVEL0; + imageView_->SetBlurLevel(level); + EXPECT_EQ(imageView_->GetBlurLevel(), level); +} + +/** + * @tc.name: UIImageViewSetTransformAlgorithm_001 + * @tc.desc: Verify SetTransformAlgorithm function, equal. + * @tc.type: FUNC + * @tc.require: AR000DSMQ1 + */ +HWTEST_F(UIImageViewTest, UIImageViewSetTransformAlgorithm_001, TestSize.Level0) +{ + if (imageView_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + TransformAlgorithm algorithm = NEAREST_NEIGHBOR; + imageView_->SetTransformAlgorithm(algorithm); + EXPECT_EQ(imageView_->GetTransformAlgorithm(), algorithm); +} +} // namespace OHOS \ No newline at end of file diff --git a/test/unittest/components/ui_label_button_unit_test.cpp b/test/unittest/components/ui_label_button_unit_test.cpp new file mode 100644 index 0000000..835e993 --- /dev/null +++ b/test/unittest/components/ui_label_button_unit_test.cpp @@ -0,0 +1,207 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "components/ui_label_button.h" + +#include +#include +#include "font/ui_font.h" + +using namespace testing::ext; +namespace OHOS { +class UILabelButtonTest : public testing::Test { +public: + static void SetUpTestCase(); + static void TearDownTestCase(); + static UILabelButton* labelBtn_; +}; + +UILabelButton* UILabelButtonTest::labelBtn_ = nullptr; + +void UILabelButtonTest::SetUpTestCase() +{ + if (labelBtn_ == nullptr) { + labelBtn_ = new UILabelButton(); + } +} + +void UILabelButtonTest::TearDownTestCase() +{ + if (labelBtn_ != nullptr) { + delete labelBtn_; + labelBtn_ = nullptr; + } +} + +/** + * @tc.name: UILabelButtonGetViewType_001 + * @tc.desc: Verify GetViewType function. + * @tc.type: FUNC + * @tc.require: AR000EEMQ5 + */ +HWTEST_F(UILabelButtonTest, UILabelButtonGetViewType_001, TestSize.Level1) +{ + if (labelBtn_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + EXPECT_EQ(labelBtn_->GetViewType(), UI_LABEL_BUTTON); +} + +/** + * @tc.name: UILabelButtonSetText_001 + * @tc.desc: Verify SetText function. + * @tc.type: FUNC + * @tc.require: AR000EEMQ5 + */ +HWTEST_F(UILabelButtonTest, UILabelButtonSetText_001, TestSize.Level1) +{ + if (labelBtn_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + const char* text = "abc"; + + labelBtn_->SetText(text); + if (labelBtn_->GetText() == nullptr) { + EXPECT_NE(0, 0); + return; + } + EXPECT_EQ(strcmp(labelBtn_->GetText(), text), 0); +} +/** + * @tc.name: UILabelButtonSetLablePosition_001 + * @tc.desc: Verify SetLablePosition function. + * @tc.type: FUNC + * @tc.require: AR000EEMQ5 + */ +HWTEST_F(UILabelButtonTest, UILabelButtonSetLablePosition_001, TestSize.Level0) +{ + if (labelBtn_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + const int16_t posX = 10; + const int16_t posY = 20; + + labelBtn_->SetLablePosition(posX, posY); + EXPECT_EQ(labelBtn_->GetLabelPosition().x, posX); + EXPECT_EQ(labelBtn_->GetLabelPosition().y, posY); +} + +/** + * @tc.name: UILabelButtonSetAlign_001 + * @tc.desc: Verify SetAlign function. + * @tc.type: FUNC + * @tc.require: AR000EEMQ5 + */ +HWTEST_F(UILabelButtonTest, UILabelButtonSetAlign_001, TestSize.Level0) +{ + if (labelBtn_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + labelBtn_->SetAlign(UITextLanguageAlignment::TEXT_ALIGNMENT_RIGHT); + EXPECT_EQ(labelBtn_->GetAlign(), UITextLanguageAlignment::TEXT_ALIGNMENT_RIGHT); +} + +/** + * @tc.name: UILabelButtonSetDirect_001 + * @tc.desc: Verify SetDirect function. + * @tc.type: FUNC + * @tc.require: AR000EEMQ5 + */ +HWTEST_F(UILabelButtonTest, UILabelButtonSetDirect_001, TestSize.Level0) +{ + if (labelBtn_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + labelBtn_->SetDirect(UITextLanguageDirect::TEXT_DIRECT_RTL); + EXPECT_EQ(labelBtn_->GetDirect(), UITextLanguageDirect::TEXT_DIRECT_RTL); +} + +/** + * @tc.name: UILabelButtonSetLabelStyle_001 + * @tc.desc: Verify SetLabelStyle function. + * @tc.type: FUNC + * @tc.require: AR000EEMQ5 + */ +HWTEST_F(UILabelButtonTest, UILabelButtonSetLabelStyle_001, TestSize.Level0) +{ + if (labelBtn_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + Style style; + style.borderWidth_ = 1; + + labelBtn_->SetLabelStyle(style); + EXPECT_EQ(labelBtn_->GetLabelStyle().borderWidth_, style.borderWidth_); +} + +/** + * @tc.name: UILabelButtonSetLabelStyle_002 + * @tc.desc: Verify SetLabelStyle function. + * @tc.type: FUNC + * @tc.require: AR000EEMQ5 + */ +HWTEST_F(UILabelButtonTest, UILabelButtonSetLabelStyle_002, TestSize.Level1) +{ + if (labelBtn_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + labelBtn_->SetLabelStyle(STYLE_BORDER_OPA, OPA_TRANSPARENT); + EXPECT_EQ(labelBtn_->GetLabelStyle(STYLE_BORDER_OPA), OPA_TRANSPARENT); +} + +/** + * @tc.name: UILabelButtonSetTextColor_001 + * @tc.desc: Verify SetTextColor function. + * @tc.type: FUNC + * @tc.require: AR000EEMQ5 + */ +HWTEST_F(UILabelButtonTest, UILabelButtonSetTextColor_001, TestSize.Level0) +{ + if (labelBtn_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + labelBtn_->SetTextColor(Color::Gray()); + EXPECT_EQ(labelBtn_->GetLabelStyle().textColor_.full, Color::Gray().full); +} + +/** + * @tc.name: UILabelButtonSetFont_001 + * @tc.desc: Verify SetFontId function. + * @tc.type: FUNC + * @tc.require: AR000EEMQ5 + */ +HWTEST_F(UILabelButtonTest, UILabelButtonSetFontId_001, TestSize.Level0) +{ + if (labelBtn_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + const uint8_t fontId = 16; + labelBtn_->SetFontId(fontId); + if (!UIFont::GetInstance()->IsVectorFont()) { + EXPECT_EQ(labelBtn_->GetFontId(), fontId); + } else { + EXPECT_EQ(labelBtn_->GetFontId(), 0); + } +} +} // namespace OHOS \ No newline at end of file diff --git a/test/unittest/components/ui_label_unit_test.cpp b/test/unittest/components/ui_label_unit_test.cpp new file mode 100755 index 0000000..9a94ce0 --- /dev/null +++ b/test/unittest/components/ui_label_unit_test.cpp @@ -0,0 +1,227 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "components/ui_label.h" + +#include +#include + +using namespace testing::ext; +namespace OHOS { +namespace { + const int16_t INIT_WIDTH = 100; + const int16_t INIT_HEIGHT = 150; +} + +class UILabelTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + static UILabel* label_; +}; + +UILabel* UILabelTest::label_ = nullptr; + +void UILabelTest::SetUpTestCase(void) +{ + if (label_ == nullptr) { + label_ = new UILabel(); + } +} + +void UILabelTest::TearDownTestCase(void) +{ + if (label_ != nullptr) { + delete label_; + label_ = nullptr; + } +} + +/** + * @tc.name: UILabelGetViewType_001 + * @tc.desc: Verify GetViewType and GetHeight function. + * @tc.type: FUNC + * @tc.require: AR000DSMQ1 + */ +HWTEST_F(UILabelTest, UILabelGetViewType_001, TestSize.Level0) +{ + if (label_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + EXPECT_EQ(label_->GetViewType(), UI_LABEL); +} + +/** + * @tc.name: UILabelResize_001 + * @tc.desc: Verify Resize function. + * @tc.type: FUNC + * @tc.require: AR000DSMQ1 + */ +HWTEST_F(UILabelTest, UILabelResize_001, TestSize.Level0) +{ + if (label_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + label_->Resize(INIT_WIDTH, INIT_HEIGHT); + EXPECT_EQ(label_->GetWidth(), INIT_WIDTH); + EXPECT_EQ(label_->GetHeight(), INIT_HEIGHT); +} + +/** + * @tc.name: UILabelSetText_001 + * @tc.desc: Verify SetText function. + * @tc.type: FUNC + * @tc.require: AR000DSMQ1 + */ +HWTEST_F(UILabelTest, UILabelSetText_001, TestSize.Level0) +{ + if (label_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + const char* text = "abc"; + label_->Resize(INIT_WIDTH, INIT_HEIGHT); + label_->SetText(text); + + const char* text0 = label_->GetText(); + ASSERT_TRUE(text0); + EXPECT_EQ(strcmp(text0, text), 0); +} + +/** + * @tc.name: UILabelSetLineBreakMode_001 + * @tc.desc: Verify SetLineBreakMode function. + * @tc.type: FUNC + * @tc.require: AR000DSMQ1 + */ +HWTEST_F(UILabelTest, UILabelSetLineBreakMode_001, TestSize.Level0) +{ + if (label_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + const uint8_t lineBreakMode = UILabel::LINE_BREAK_ELLIPSIS; + + label_->SetLineBreakMode(lineBreakMode); + EXPECT_EQ(label_->GetLineBreakMode(), lineBreakMode); +} + +/** + * @tc.name: UILabelSetTextColor_001 + * @tc.desc: Verify SetTextColor function. + * @tc.type: FUNC + * @tc.require: AR000DSMQ1 + */ +HWTEST_F(UILabelTest, UILabelSetTextColor_001, TestSize.Level0) +{ + if (label_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + ColorType color = Color::White(); + + label_->SetTextColor(color); + EXPECT_EQ(label_->GetTextColor().full, color.full); +} + +/** + * @tc.name: UILabelSetLongMode_001 + * @tc.desc: Verify SetLongMode function. + * @tc.type: FUNC + * @tc.require: AR000DSMQ1 + */ +HWTEST_F(UILabelTest, UILabelSetLongMode_001, TestSize.Level0) +{ + if (label_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + label_->SetLineBreakMode(UILabel::LINE_BREAK_ADAPT); + EXPECT_EQ(label_->GetLineBreakMode(), UILabel::LINE_BREAK_ADAPT); +} + +/** + * @tc.name: UILabelSetAlign_001 + * @tc.desc: Verify SetAlign function. + * @tc.type: FUNC + * @tc.require: AR000DSMQ1 + */ +HWTEST_F(UILabelTest, UILabelSetAlign_001, TestSize.Level0) +{ + if (label_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + label_->SetAlign(UITextLanguageAlignment::TEXT_ALIGNMENT_RIGHT, UITextLanguageAlignment::TEXT_ALIGNMENT_BOTTOM); + EXPECT_EQ(label_->GetHorAlign(), UITextLanguageAlignment::TEXT_ALIGNMENT_RIGHT); + EXPECT_EQ(label_->GetVerAlign(), UITextLanguageAlignment::TEXT_ALIGNMENT_BOTTOM); +} + +/** + * @tc.name: UILabelSetDirect_001 + * @tc.desc: Verify SetDirect function. + * @tc.type: FUNC + * @tc.require: AR000DSMQ1 + */ +HWTEST_F(UILabelTest, UILabelSetDirect_001, TestSize.Level0) +{ + if (label_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + label_->SetDirect(UITextLanguageDirect::TEXT_DIRECT_RTL); + EXPECT_EQ(label_->GetDirect(), UITextLanguageDirect::TEXT_DIRECT_RTL); +} + +/** + * @tc.name: UILabelSetRollStartPos_001 + * @tc.desc: Verify SetRollStartPos function. + * @tc.type: FUNC + * @tc.require: AR000DSMQ1 + */ +HWTEST_F(UILabelTest, UILabelSetRollStartPos_001, TestSize.Level0) +{ + if (label_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + const int16_t rollStartPos = 50; + + label_->SetRollStartPos(rollStartPos); + EXPECT_EQ(label_->GetRollStartPos(), rollStartPos); +} + +/** + * @tc.name: UILabelSetFont_001 + * @tc.desc: Verify SetFont function. + * @tc.type: FUNC + * @tc.require: AR000DSMQ1 + */ +HWTEST_F(UILabelTest, UILabelSetFont_001, TestSize.Level0) +{ + if (label_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + uint8_t fontId = label_->GetFontId(); + + const uint8_t fontSize = 20; // 20: font size for test + label_->SetFont("error_font_name", fontSize); + + EXPECT_EQ(label_->GetFontId(), fontId); +} +} // namespace OHOS \ No newline at end of file diff --git a/test/unittest/components/ui_picker_unit_test.cpp b/test/unittest/components/ui_picker_unit_test.cpp new file mode 100755 index 0000000..118af92 --- /dev/null +++ b/test/unittest/components/ui_picker_unit_test.cpp @@ -0,0 +1,171 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "components/ui_picker.h" +#include +#include +#include "style.h" + +using namespace testing::ext; +namespace OHOS { +class UIPickerTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + static UIPicker* picker_; +}; + +UIPicker* UIPickerTest::picker_ = nullptr; + +void UIPickerTest::SetUpTestCase(void) +{ + if (picker_ == nullptr) { + picker_ = new UIPicker(); + } +} + +void UIPickerTest::TearDownTestCase(void) +{ + if (picker_ != nullptr) { + delete picker_; + picker_ = nullptr; + } +} + +/** + * @tc.name: UIPickerGetViewType_001 + * @tc.desc: Verify GetViewType function, equal. + * @tc.type: FUNC + * @tc.require: AR000EEMQ6 + */ +HWTEST_F(UIPickerTest, UIPickerGetViewType_001, TestSize.Level0) +{ + if (picker_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + EXPECT_EQ(picker_->GetViewType(), UI_PICKER); +} + +/** + * @tc.name: UIPickerGetHighlightFontId_001 + * @tc.desc: Verify GetHighlightFontId function, equal. + * @tc.type: FUNC + * @tc.require: AR000EEMQ6 + */ +HWTEST_F(UIPickerTest, UIPickerGetHighlightFontId_001, TestSize.Level0) +{ + if (picker_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + uint8_t highlightFontId = StyleDefault::GetPickerHighlightStyle().font_; + EXPECT_EQ(picker_->GetHighlightFontId(), highlightFontId); +} + +/** + * @tc.name: UIPickerSetFontId_001 + * @tc.desc: Verify SetFontId function, equal. + * @tc.type: FUNC + * @tc.require: AR000EEMQ6 + */ +HWTEST_F(UIPickerTest, UIPickerSetFontId_001, TestSize.Level0) +{ + if (picker_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + const uint8_t backgroundFontId = 16; + const uint8_t highlightFontId = 18; + + picker_->SetFontId(backgroundFontId, highlightFontId); + EXPECT_EQ(picker_->GetBackgroundFontId(), backgroundFontId); + EXPECT_EQ(picker_->GetHighlightFontId(), highlightFontId); +} + +/** + * @tc.name: UIPickerSetTextColor_001 + * @tc.desc: Verify SetTextColor function, equal. + * @tc.type: FUNC + * @tc.require: AR000EEMQ6 + */ +HWTEST_F(UIPickerTest, UIPickerSetTextColor_001, TestSize.Level0) +{ + if (picker_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + ColorType backgroundColor; + ColorType highlightColor; + backgroundColor.alpha = OPA_OPAQUE; + highlightColor.alpha = OPA_OPAQUE; + + picker_->SetTextColor(backgroundColor, highlightColor); + EXPECT_EQ(picker_->GetBackgroundTextColor().alpha, backgroundColor.alpha); + EXPECT_EQ(picker_->GetHighlightTextColor().alpha, highlightColor.alpha); +} + +/** + * @tc.name: UIPickerSetWidth_001 + * @tc.desc: Verify SetWidth function, equal. + * @tc.type: FUNC + * @tc.require: AR000EEMQ6 + */ +HWTEST_F(UIPickerTest, UIPickerSetWidth_001, TestSize.Level0) +{ + if (picker_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + const int16_t width = 10; + const int16_t height = 20; + + picker_->SetWidth(width); + picker_->SetHeight(height); + EXPECT_EQ(picker_->GetWidth(), width); + EXPECT_EQ(picker_->GetHeight(), height); +} + + +/** + * @tc.name: UIPickerSetSelected_001 + * @tc.desc: Verify SetSelected function, equal. + * @tc.type: FUNC + * @tc.require: AR000EEMQ6 + */ +HWTEST_F(UIPickerTest, UIPickerSetSelected_001, TestSize.Level0) +{ + if (picker_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + const uint16_t index = 30; + const int16_t itemHeight = 10; + const int16_t width = 100; + const int16_t height = 100; + const int16_t startValue= 0; + const int16_t endValue = 100; + picker_->SetPosition(0, 0, width, height); + picker_->SetItemHeight(itemHeight); + picker_->SetValues(startValue, endValue); + const char* value[1]; + + value[0] = "abc"; + picker_->SetValues(value, 1); + picker_->SetValues(startValue, endValue); + picker_->SetSelected(index); + EXPECT_EQ(picker_->GetSelected(), index); +} +} diff --git a/test/unittest/components/ui_qrcode_unit_test.cpp b/test/unittest/components/ui_qrcode_unit_test.cpp new file mode 100644 index 0000000..e2a3663 --- /dev/null +++ b/test/unittest/components/ui_qrcode_unit_test.cpp @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "components/ui_qrcode.h" + +#include +#include + +using namespace testing::ext; +namespace OHOS { +namespace { + const int16_t WIDTH = 100; + const int16_t HEIGHT = 100; +} +class UIQrcodeTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + static UIQrcode* qrcode_; +}; + +UIQrcode* UIQrcodeTest::qrcode_ = nullptr; + +void UIQrcodeTest::SetUpTestCase() +{ + if (qrcode_ == nullptr) { + qrcode_ = new UIQrcode(); + } +} + +void UIQrcodeTest::TearDownTestCase() +{ + if (qrcode_ != nullptr) { + delete qrcode_; + qrcode_ = nullptr; + } +} + +/** + * @tc.name: Graphic_UIQrcodeTest_Test_GetViewType_001 + * @tc.desc: Verify GetViewType function. + * @tc.type: FUNC + * @tc.require: AR000F4E5M + */ +HWTEST_F(UIQrcodeTest, Graphic_UIQrcodeTest_Test_GetViewType_001, TestSize.Level0) +{ + if (qrcode_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + EXPECT_EQ(qrcode_->GetViewType(), UI_QRCODE); +} + +/** + * @tc.name: Graphic_UIQrcodeTest_Test_SetWidth_001 + * @tc.desc: Verify SetWidth function. + * @tc.type: FUNC + * @tc.require: AR000F4E5M + */ +HWTEST_F(UIQrcodeTest, Graphic_UIQrcodeTest_Test_SetWidth_001, TestSize.Level0) +{ + if (qrcode_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + qrcode_->SetWidth(WIDTH); + EXPECT_EQ(qrcode_->GetWidth(), WIDTH); +} + +/** + * @tc.name: Graphic_UIQrcodeTest_Test_SetHeight_001 + * @tc.desc: Verify SetHeight function. + * @tc.type: FUNC + * @tc.require: SR000F3PEF + */ +HWTEST_F(UIQrcodeTest, Graphic_UIQrcodeTest_Test_SetHeight_001, TestSize.Level0) +{ + if (qrcode_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + qrcode_->SetHeight(HEIGHT); + EXPECT_EQ(qrcode_->GetHeight(), HEIGHT); +} +} // namespace OHOS diff --git a/test/unittest/components/ui_radio_button_unit_test.cpp b/test/unittest/components/ui_radio_button_unit_test.cpp new file mode 100755 index 0000000..56feff1 --- /dev/null +++ b/test/unittest/components/ui_radio_button_unit_test.cpp @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "components/ui_radio_button.h" + +#include +#include +#include "components/root_view.h" +using namespace testing::ext; +namespace OHOS { +class UIRadioButtonTest : public testing::Test { +public: + static void SetUpTestCase(); + static void TearDownTestCase(); + static UIRadioButton* radioBtn_; +}; + +UIRadioButton* UIRadioButtonTest::radioBtn_ = nullptr; + +void UIRadioButtonTest::SetUpTestCase() +{ + if (radioBtn_ == nullptr) { + radioBtn_ = new UIRadioButton(); + } +} + +void UIRadioButtonTest::TearDownTestCase() +{ + if (radioBtn_ != nullptr) { + delete radioBtn_; + radioBtn_ = nullptr; + } +} + +/** + * @tc.name: UIRadioButtonGetViewType_001 + * @tc.desc: Verify GetViewType function, equal. + * @tc.type: FUNC + * @tc.require: AR000DSMQB + */ +HWTEST_F(UIRadioButtonTest, UIRadioButtonGetViewType_001, TestSize.Level0) +{ + if (radioBtn_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + EXPECT_EQ(radioBtn_->GetViewType(), UI_RADIO_BUTTON); +} + +/** + * @tc.name: UIRadioButtonGetName_001 + * @tc.desc: Verify GetName function, equal. + * @tc.type: FUNC + * @tc.require: AR000F4E5I + */ +HWTEST_F(UIRadioButtonTest, UIRadioButtonGetName_001, TestSize.Level0) +{ + if (radioBtn_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + const char* name = "group"; + radioBtn_->SetName(name); + if (radioBtn_->GetName() == nullptr) { + EXPECT_NE(0, 0); + return; + } + EXPECT_EQ(strcmp(radioBtn_->GetName(), name), 0); +} + +/** + * @tc.name: UIRadioButtonSetName_001 + * @tc.desc: Verify SetName function, equal. + * @tc.type: FUNC + * @tc.require: SR000F3PEE + */ +HWTEST_F(UIRadioButtonTest, UIRadioButtonSetName_001, TestSize.Level0) +{ + if (radioBtn_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + const char* name1 = "group1"; + const char* name2 = "group2"; + UIRadioButton* radioBtn1 = new UIRadioButton(name1); + UIRadioButton* radioBtn2 = new UIRadioButton(); + radioBtn2->SetName(name1); + UIRadioButton* radioBtn3 = new UIRadioButton(name1); + UIRadioButton* radioBtn4 = new UIRadioButton(name2); + UIRadioButton* radioBtn5 = new UIRadioButton(name2); + UIViewGroup* view = static_cast(RootView::GetInstance()); + view->Add(radioBtn1); + view->Add(radioBtn2); + view->Add(radioBtn3); + view->Add(radioBtn4); + view->Add(radioBtn5); + + ClickEvent event({0, 0}); + radioBtn2->OnClickEvent(event); + EXPECT_EQ(radioBtn1->GetState(), UICheckBox::UICheckBoxState::UNSELECTED); + EXPECT_EQ(radioBtn2->GetState(), UICheckBox::UICheckBoxState::SELECTED); + EXPECT_EQ(radioBtn3->GetState(), UICheckBox::UICheckBoxState::UNSELECTED); + EXPECT_EQ(radioBtn4->GetState(), UICheckBox::UICheckBoxState::UNSELECTED); + EXPECT_EQ(radioBtn5->GetState(), UICheckBox::UICheckBoxState::UNSELECTED); + + radioBtn4->OnClickEvent(event); + EXPECT_EQ(radioBtn1->GetState(), UICheckBox::UICheckBoxState::UNSELECTED); + EXPECT_EQ(radioBtn2->GetState(), UICheckBox::UICheckBoxState::SELECTED); + EXPECT_EQ(radioBtn3->GetState(), UICheckBox::UICheckBoxState::UNSELECTED); + EXPECT_EQ(radioBtn4->GetState(), UICheckBox::UICheckBoxState::SELECTED); + EXPECT_EQ(radioBtn5->GetState(), UICheckBox::UICheckBoxState::UNSELECTED); + + radioBtn1->OnClickEvent(event); + EXPECT_EQ(radioBtn1->GetState(), UICheckBox::UICheckBoxState::SELECTED); + EXPECT_EQ(radioBtn2->GetState(), UICheckBox::UICheckBoxState::UNSELECTED); + EXPECT_EQ(radioBtn3->GetState(), UICheckBox::UICheckBoxState::UNSELECTED); + EXPECT_EQ(radioBtn4->GetState(), UICheckBox::UICheckBoxState::SELECTED); + EXPECT_EQ(radioBtn5->GetState(), UICheckBox::UICheckBoxState::UNSELECTED); + + view->Remove(radioBtn1); + view->Remove(radioBtn2); + view->Remove(radioBtn3); + view->Remove(radioBtn4); + view->Remove(radioBtn5); + delete radioBtn1; + delete radioBtn2; + delete radioBtn3; + delete radioBtn4; + delete radioBtn5; +} +} // namespace OHOS \ No newline at end of file diff --git a/test/unittest/components/ui_repeat_button_unit_test.cpp b/test/unittest/components/ui_repeat_button_unit_test.cpp new file mode 100755 index 0000000..224fe16 --- /dev/null +++ b/test/unittest/components/ui_repeat_button_unit_test.cpp @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "components/ui_repeat_button.h" + +#include +#include + +using namespace testing::ext; +namespace OHOS { +class UIRepeatButtonTest : public testing::Test { +public: + static void SetUpTestCase(); + static void TearDownTestCase(); + static UIRepeatButton* repeatBtn_; +}; + +UIRepeatButton* UIRepeatButtonTest::repeatBtn_ = nullptr; + +void UIRepeatButtonTest::SetUpTestCase() +{ + if (repeatBtn_ == nullptr) { + repeatBtn_ = new UIRepeatButton(); + } +} + +void UIRepeatButtonTest::TearDownTestCase() +{ + if (repeatBtn_ != nullptr) { + delete repeatBtn_; + repeatBtn_ = nullptr; + } +} + +/** + * @tc.name: UIRepeatButtonGetViewType_001 + * @tc.desc: Verify GetViewType function, equal. + * @tc.type: FUNC + * @tc.require: SR000DRSH1 + */ +HWTEST_F(UIRepeatButtonTest, UIRepeatButtonTestGetViewType_001, TestSize.Level0) +{ + if (repeatBtn_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + EXPECT_EQ(repeatBtn_->GetViewType(), UI_REPEAT_BUTTON); +} + +/** + * @tc.name: UIRepeatButtonSetInterval_001 + * @tc.desc: Verify SetInterval function, equal. + * @tc.type: FUNC + * @tc.require: SR000DRSH1 + */ +HWTEST_F(UIRepeatButtonTest, UIRepeatButtonSetInterval_001, TestSize.Level0) +{ + if (repeatBtn_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + const uint16_t interval = 10; + repeatBtn_->SetInterval(interval); + EXPECT_EQ(repeatBtn_->GetInterval(), interval); +} +} // namespace OHOS \ No newline at end of file diff --git a/test/unittest/components/ui_scroll_view_unit_test.cpp b/test/unittest/components/ui_scroll_view_unit_test.cpp new file mode 100755 index 0000000..03f4ba6 --- /dev/null +++ b/test/unittest/components/ui_scroll_view_unit_test.cpp @@ -0,0 +1,205 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "components/ui_scroll_view.h" +#include +#include + +using namespace testing::ext; +namespace OHOS { +namespace { + constexpr uint8_t DEFAULT_BAR_WIDTH = 5; +} + +class ScrollViewTest : public testing::Test { +public: + static void SetUpTestCase(); + static void TearDownTestCase(); + static UIScrollView* scrollView_; +}; + +UIScrollView* ScrollViewTest::scrollView_ = nullptr; + +void ScrollViewTest::SetUpTestCase() +{ + if (scrollView_ == nullptr) { + scrollView_ = new UIScrollView(); + } +} + +void ScrollViewTest::TearDownTestCase() +{ + if (scrollView_ != nullptr) { + delete scrollView_; + scrollView_ = nullptr; + } +} + +/** + * @tc.name: UIScrollViewSetScrollState_001 + * @tc.desc: Verify SetScrollState function, equal. + * @tc.type: FUNC + * @tc.require: AR000DSMQE + */ +HWTEST_F(ScrollViewTest, UIScrollViewSetScrollState_001, TestSize.Level0) +{ + UIScrollView::OnScrollListener* scrollListener = new UIScrollView::OnScrollListener(); + if (scrollListener == nullptr) { + EXPECT_NE(0, 0); + return; + } + uint8_t state = UIScrollView::OnScrollListener::SCROLL_STATE_MOVE; + scrollListener->SetScrollState(state); + EXPECT_EQ(scrollListener->GetScrollState(), state); + + state = UIScrollView::OnScrollListener::SCROLL_STATE_STOP; + scrollListener->SetScrollState(state); + EXPECT_EQ(scrollListener->GetScrollState(), state); + delete scrollListener; +} + +/** + * @tc.name: UIScrollViewGetViewType_001 + * @tc.desc: Verify GetViewType function, equal. + * @tc.type: FUNC + * @tc.require: AR000DSMQE + */ +HWTEST_F(ScrollViewTest, UIScrollViewGetViewType_001, TestSize.Level0) +{ + if (scrollView_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + EXPECT_EQ(scrollView_->GetViewType(), UI_SCROLL_VIEW); +} + +/** + * @tc.name: UIScrollViewSetHorizontalScrollState_001 + * @tc.desc: Verify SetHorizontalScrollState function, equal. + * @tc.type: FUNC + * @tc.require: AR000DSMQE + */ +HWTEST_F(ScrollViewTest, UIScrollViewSetHorizontalScrollState_001, TestSize.Level0) +{ + if (scrollView_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + scrollView_->SetHorizontalScrollState(false); + EXPECT_EQ(scrollView_->GetHorizontalScrollState(), false); + + scrollView_->SetHorizontalScrollState(true); + EXPECT_EQ(scrollView_->GetHorizontalScrollState(), true); +} + +/** + * @tc.name: UIScrollViewSetVerticalScrollState_001 + * @tc.desc: Verify SetVerticalScrollState function, equal. + * @tc.type: FUNC + * @tc.require: AR000DSMQE + */ +HWTEST_F(ScrollViewTest, UIScrollViewSetVerticalScrollState_001, TestSize.Level0) +{ + if (scrollView_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + scrollView_->SetVerticalScrollState(false); + EXPECT_EQ(scrollView_->GetVerticalScrollState(), false); + + scrollView_->SetVerticalScrollState(true); + EXPECT_EQ(scrollView_->GetVerticalScrollState(), true); +} + +/** + * @tc.name: UIScrollViewSetMaxScrollDistance_001 + * @tc.desc: Verify SetMaxScrollDistance function, equal. + * @tc.type: FUNC + * @tc.require: AR000E2RJK + */ +HWTEST_F(ScrollViewTest, UIScrollViewSetMaxScrollDistance_001, TestSize.Level0) +{ + if (scrollView_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + const uint16_t distance = 10; + scrollView_->SetMaxScrollDistance(distance); + EXPECT_EQ(scrollView_->GetMaxScrollDistance(), distance); +} + +/** + * @tc.name: UIScrollViewSetDragACCLevel_001 + * @tc.desc: Verify SetDragACCLevel function, equal. + * @tc.type: FUNC + * @tc.require: SR000E2RJJ + */ +HWTEST_F(ScrollViewTest, UIScrollViewSetDragACCLevel_001, TestSize.Level0) +{ + if (scrollView_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + const uint16_t value = 10; + scrollView_->SetDragACCLevel(value); + EXPECT_EQ(scrollView_->GetDragACCLevel(), value); +} + +/** + * @tc.name: UIScrollViewSetSwipeACCLevel_001 + * @tc.desc: Verify SetSwipeACCLevel function, equal. + * @tc.type: FUNC + * @tc.require: AR000F4E5P + */ +HWTEST_F(ScrollViewTest, UIScrollViewSetSwipeACCLevel_001, TestSize.Level0) +{ + if (scrollView_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + const uint16_t value = 10; + scrollView_->SetSwipeACCLevel(value); + EXPECT_EQ(scrollView_->GetSwipeACCLevel(), value); +} + +/** + * @tc.name: UIScrollViewMoveChildByOffset_001 + * @tc.desc: Verify MoveChildByOffset function, equal. + * @tc.type: FUNC + * @tc.require: SR000F3PEM + */ +HWTEST_F(ScrollViewTest, UIScrollViewMoveChildByOffset_001, TestSize.Level0) +{ + if (scrollView_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + UIView* view = new UIView(); + EXPECT_EQ(view->GetX(), 0); + EXPECT_EQ(view->GetY(), 0); + + scrollView_->Add(view); + + const int16_t offsetX = 10; + const int16_t offsetY = 20; + scrollView_->SetThrowDrag(true); + scrollView_->MoveChildByOffset(offsetX, offsetY); + EXPECT_EQ(view->GetX(), offsetX); + EXPECT_EQ(view->GetY(), offsetY); + + scrollView_->Remove(view); + delete view; +} +} // namespace OHOS diff --git a/test/unittest/components/ui_slider_unit_test.cpp b/test/unittest/components/ui_slider_unit_test.cpp new file mode 100755 index 0000000..1c3c153 --- /dev/null +++ b/test/unittest/components/ui_slider_unit_test.cpp @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "components/ui_slider.h" +#include +#include + +using namespace testing::ext; +namespace OHOS { +class UISliderTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + static UISlider* slider_; +}; + +UISlider* UISliderTest::slider_ = nullptr; + +void UISliderTest::SetUpTestCase(void) +{ + if (slider_ == nullptr) { + slider_ = new UISlider(); + } +} + +void UISliderTest::TearDownTestCase(void) +{ + if (slider_ != nullptr) { + delete slider_; + slider_ = nullptr; + } +} + +/** + * @tc.name:UISliderGetViewType_001 + * @tc.desc: Verify GetViewType function, equal. + * @tc.type: FUNC + * @tc.require: NA + */ +HWTEST_F(UISliderTest, UISliderGetViewType_001, TestSize.Level0) +{ + if (slider_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + EXPECT_EQ(slider_->GetViewType(), UI_SLIDER); +} + +/** + * @tc.name:UISliderSetKnobWidth_001 + * @tc.desc: Verify SetKnobWidth function, equal. + * @tc.type: FUNC + * @tc.require: NA + */ +HWTEST_F(UISliderTest, UISliderSetKnobWidth_001, TestSize.Level0) +{ + if (slider_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + const int16_t width = 10; + + slider_->SetKnobWidth(width); + EXPECT_EQ(slider_->GetKnobWidth(), width); +} + +/** + * @tc.name:UISliderSetKnobStyle_001 + * @tc.desc: Verify SetKnobStyle function, equal. + * @tc.type: FUNC + * @tc.require: NA + */ +HWTEST_F(UISliderTest, UISliderSetKnobStyle_001, TestSize.Level0) +{ + if (slider_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + slider_->SetKnobStyle(STYLE_BACKGROUND_COLOR, Color::Gray().full); + EXPECT_EQ(slider_->GetKnobStyle().bgColor_.full, Color::Gray().full); +} +} // namespace OHOS \ No newline at end of file diff --git a/test/unittest/components/ui_surface_view_unit_test.cpp b/test/unittest/components/ui_surface_view_unit_test.cpp new file mode 100755 index 0000000..5640027 --- /dev/null +++ b/test/unittest/components/ui_surface_view_unit_test.cpp @@ -0,0 +1,183 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "components/ui_surface_view.h" + +#include +#include + +using namespace testing::ext; +namespace OHOS { +namespace { + const int16_t INIT_POS_X = 10; + const int16_t INIT_POS_Y = 20; + const int16_t INIT_WIDTH = 50; + const int16_t INIT_HEIGHT = 30; +} + +class UISurfaceViewTest : public testing::Test { +public: + UISurfaceViewTest() : surface_(nullptr) {} + virtual ~UISurfaceViewTest() {} + static void SetUpTestCase(); + static void TearDownTestCase(); + void SetUp(); + void TearDown(); + UISurfaceView* surface_; +}; + +void UISurfaceViewTest::SetUpTestCase() +{ +} + +void UISurfaceViewTest::TearDownTestCase() +{ +} + +void UISurfaceViewTest::SetUp() +{ + if (surface_ == nullptr) { + surface_ = new UISurfaceView(); + } +} + +void UISurfaceViewTest::TearDown() +{ + if (surface_ != nullptr) { + delete surface_; + surface_ = nullptr; + } +} +/** + * @tc.name: UISurfaceViewSetPosition_001 + * @tc.desc: Verify SetPosition function, equal. + * @tc.type: FUNC + * @tc.require: AR000EEMQJ + */ +HWTEST_F(UISurfaceViewTest, UISurfaceViewSetPosition_001, TestSize.Level0) +{ + if (surface_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + surface_->SetPosition(INIT_POS_X, INIT_POS_Y); + EXPECT_EQ(surface_->GetX(), INIT_POS_X); + EXPECT_EQ(surface_->GetY(), INIT_POS_Y); + + surface_->SetPosition(INIT_POS_X + 1, INIT_POS_Y + 1, INIT_WIDTH, INIT_HEIGHT); + EXPECT_EQ(surface_->GetX(), INIT_POS_X + 1); + EXPECT_EQ(surface_->GetY(), INIT_POS_Y + 1); + EXPECT_EQ(surface_->GetWidth(), INIT_WIDTH); + EXPECT_EQ(surface_->GetHeight(), INIT_HEIGHT); +} + +/** + * @tc.name: UISurfaceViewResize_001 + * @tc.desc: Verify Resize function, equal. + * @tc.type: FUNC + * @tc.require: AR000EEMQJ + */ +HWTEST_F(UISurfaceViewTest, UISurfaceViewResize_001, TestSize.Level0) +{ + if (surface_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + surface_->Resize(INIT_WIDTH, INIT_HEIGHT); + EXPECT_EQ(surface_->GetWidth(), INIT_WIDTH); + EXPECT_EQ(surface_->GetHeight(), INIT_HEIGHT); +} + +/** + * @tc.name: UISurfaceViewSetX_001 + * @tc.desc: Verify SetX function, equal. + * @tc.type: FUNC + * @tc.require: AR000EEMQJ + */ +HWTEST_F(UISurfaceViewTest, UISurfaceViewSetX_001, TestSize.Level0) +{ + if (surface_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + surface_->SetX(INIT_POS_X); + EXPECT_EQ(surface_->GetX(), INIT_POS_X); +} + +/** + * @tc.name: UISurfaceViewSetY_001 + * @tc.desc: Verify SetY function, equal. + * @tc.type: FUNC + * @tc.require: AR000EEMQJ + */ +HWTEST_F(UISurfaceViewTest, UISurfaceViewSetY_001, TestSize.Level0) +{ + if (surface_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + surface_->SetY(INIT_POS_Y); + EXPECT_EQ(surface_->GetY(), INIT_POS_Y); +} + +/** + * @tc.name: UISurfaceViewSetWidth_001 + * @tc.desc: Verify SetWidth function, equal. + * @tc.type: FUNC + * @tc.require: AR000EEMQJ + */ +HWTEST_F(UISurfaceViewTest, UISurfaceViewSetWidth_001, TestSize.Level0) +{ + if (surface_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + surface_->SetWidth(INIT_WIDTH); + EXPECT_EQ(surface_->GetWidth(), INIT_WIDTH); +} + +/** + * @tc.name: UISurfaceViewSetHeight_001 + * @tc.desc: Verify SetHeight function, equal. + * @tc.type: FUNC + * @tc.require: AR000EEMQJ + */ +HWTEST_F(UISurfaceViewTest, UISurfaceViewSetHeight_001, TestSize.Level0) +{ + if (surface_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + surface_->SetHeight(INIT_HEIGHT); + EXPECT_EQ(surface_->GetHeight(), INIT_HEIGHT); +} + +/** + * @tc.name: UISurfaceViewSetVisible_001 + * @tc.desc: Verify SetVisible function, equal. + * @tc.type: FUNC + * @tc.require: AR000EEMQJ + */ +HWTEST_F(UISurfaceViewTest, UISurfaceViewSetVisible_001, TestSize.Level0) +{ + if (surface_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + bool visible = surface_->IsVisible(); + surface_->SetVisible(!visible); + EXPECT_EQ(surface_->IsVisible(), !visible); +} +} // namespace OHOS \ No newline at end of file diff --git a/test/unittest/components/ui_swipe_view_unit_test.cpp b/test/unittest/components/ui_swipe_view_unit_test.cpp new file mode 100755 index 0000000..3318e8c --- /dev/null +++ b/test/unittest/components/ui_swipe_view_unit_test.cpp @@ -0,0 +1,316 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "components/ui_swipe_view.h" + +#include +#include +#include "common/screen.h" + +using namespace testing::ext; +namespace OHOS { +namespace { + constexpr uint8_t HORIZONTAL = 0; + constexpr uint8_t VERTICAL = 1; + const uint16_t DEFAULT_WIDTH = 100; +} +class UISwipeViewTest : public testing::Test { +public: + UISwipeViewTest() : swipeView_(nullptr) {} + virtual ~UISwipeViewTest() {} + static void SetUpTestCase() {} + static void TearDownTestCase() {} + void SetUp(); + void TearDown(); + UISwipeView* swipeView_; +}; + +void UISwipeViewTest::SetUp() +{ + if (swipeView_ == nullptr) { + swipeView_ = new UISwipeView(); + } +} + +void UISwipeViewTest::TearDown() +{ + if (swipeView_ != nullptr) { + delete swipeView_; + swipeView_ = nullptr; + } +} +/** + * @tc.name: UISwipeViewGetViewType_001 + * @tc.desc: Verify GetViewType function, equal. + * @tc.type: FUNC + * @tc.require: AR000EEMQF + */ +HWTEST_F(UISwipeViewTest, UISwipeViewGetViewType_001, TestSize.Level0) +{ + if (swipeView_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + EXPECT_EQ(swipeView_->GetViewType(), UI_SWIPE_VIEW); +} + +/** + * @tc.name: UISwipeViewSetDirection_001 + * @tc.desc: Verify SetDirection function, equal. + * @tc.type: FUNC + * @tc.require: AR000EEMQF + */ +HWTEST_F(UISwipeViewTest, UISwipeViewSetDirection_001, TestSize.Level0) +{ + if (swipeView_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + swipeView_->SetDirection(HORIZONTAL); + EXPECT_EQ(swipeView_->GetDirection(), HORIZONTAL); + + swipeView_->SetDirection(VERTICAL); + EXPECT_EQ(swipeView_->GetDirection(), VERTICAL); +} + +/** + * @tc.name: UISwipeViewAdd_001 + * @tc.desc: Verify Add function, equal. + * @tc.type: FUNC + * @tc.require: AR000EEMQF + */ +HWTEST_F(UISwipeViewTest, UISwipeViewAdd_001, TestSize.Level0) +{ + if (swipeView_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + UIView* view = new UIView(); + if (view == nullptr) { + EXPECT_NE(0, 0); + return; + } + swipeView_->Add(view); + EXPECT_EQ(view, swipeView_->GetChildrenHead()); + EXPECT_EQ(view->GetParent(), swipeView_); + swipeView_->Remove(view); + delete view; +} + +/** + * @tc.name: UISwipeViewInsert_001 + * @tc.desc: Verify Insert function, equal. + * @tc.type: FUNC + * @tc.require: AR000EEMQF + */ +HWTEST_F(UISwipeViewTest, UISwipeViewInsert_001, TestSize.Level0) +{ + if (swipeView_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + UIView* preView = new UIView(); + if (preView == nullptr) { + EXPECT_NE(0, 0); + return; + } + UIView* view = new UIView(); + if (view == nullptr) { + delete preView; + EXPECT_NE(0, 0); + return; + } + swipeView_->Add(preView); + swipeView_->Insert(preView, view); + EXPECT_EQ(view, preView->GetNextSibling()); + + swipeView_->Remove(preView); + swipeView_->Remove(view); + delete view; + delete preView; +} + +/** + * @tc.name: UISwipeViewRemove_001 + * @tc.desc: Verify Remove function, equal. + * @tc.type: FUNC + * @tc.require: AR000EEMQF + */ +HWTEST_F(UISwipeViewTest, UISwipeViewRemove_001, TestSize.Level0) +{ + if (swipeView_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + UIView* view = new UIView(); + if (view == nullptr) { + EXPECT_NE(0, 0); + return; + } + swipeView_->Add(view); + swipeView_->Remove(view); + EXPECT_EQ(nullptr, swipeView_->GetChildrenHead()); + EXPECT_EQ(nullptr, view->GetParent()); + + delete view; +} + +/** + * @tc.name: UISwipeViewSetCurrentPage_001 + * @tc.desc: Verify SetCurrentPage function, equal. + * @tc.type: FUNC + * @tc.require: AR000EEMQF + */ +HWTEST_F(UISwipeViewTest, UISwipeViewSetCurrentPage_001, TestSize.Level0) +{ + if (swipeView_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + const int16_t initPosX = 10; + const int16_t initPosY = 20; + const int16_t initWidth = 50; + const int16_t initHeight = 30; + const uint16_t size = 100; + const uint16_t time = 100; + + swipeView_->SetPosition(initPosX, initPosY, initWidth, initHeight); + swipeView_->SetLoopState(true); + swipeView_->SetAnimatorTime(time); + swipeView_->SetBlankSize(size); + UIViewGroup* view = new UIViewGroup(); + if (view == nullptr) { + EXPECT_NE(0, 0); + return; + } + UIViewGroup* view2 = new UIViewGroup(); + if (view2 == nullptr) { + delete view; + EXPECT_NE(0, 0); + return; + } + + view->SetPosition(initPosX, initPosY, initWidth, initHeight); + swipeView_->Add(view); + view2->SetPosition(initPosX, initPosY, initWidth, initHeight); + swipeView_->Add(view2); + uint16_t index = 1; + swipeView_->SetCurrentPage(1); + EXPECT_EQ(swipeView_->GetCurrentPage(), 1); + + swipeView_->Remove(view); + swipeView_->Remove(view2); + delete view; + delete view2; +} + +class OnTestSwipeListener : public UISwipeView::OnSwipeListener { +public: + OnTestSwipeListener() {} + virtual ~OnTestSwipeListener() {} + virtual void OnSwipe(UISwipeView& view) override + { + view.SetWidth(DEFAULT_WIDTH); + return; + } +}; + +class TestUISwipeView : public UISwipeView { +public: + void TriggerStopAnimator() + { + StopAnimator(); + } +}; + +/** + * @tc.name: UISwipeViewSetOnSwipeListener_001 + * @tc.desc: Verify SetOnSwipeListener function, equal. + * @tc.type: FUNC + * @tc.require: AR000EEMQF + */ +HWTEST_F(UISwipeViewTest, UISwipeViewSetOnSwipeListener_001, TestSize.Level0) +{ + if (swipeView_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + auto testSwipeLis = new OnTestSwipeListener(); + + EXPECT_EQ(swipeView_->GetOnSwipeListener(), nullptr); + swipeView_->SetOnSwipeListener(testSwipeLis); + EXPECT_EQ(swipeView_->GetOnSwipeListener(), testSwipeLis); + + EXPECT_NE(swipeView_->GetWidth(), DEFAULT_WIDTH); + static_cast(swipeView_)->TriggerStopAnimator(); + EXPECT_EQ(swipeView_->GetWidth(), DEFAULT_WIDTH); + delete testSwipeLis; +} + +/** + * @tc.name: UISwipeViewGetViewByIndex_001 + * @tc.desc: Verify GetViewByIndex function, equal. + * @tc.type: FUNC + * @tc.require: AR000EEMQF + */ +HWTEST_F(UISwipeViewTest, UISwipeViewGetViewByIndex_001, TestSize.Level0) +{ + if (swipeView_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + swipeView_->SetDirection(HORIZONTAL); + const int16_t initWidth = 50; + const int16_t initHeight = 30; + + swipeView_->SetStyle(STYLE_BACKGROUND_COLOR, Color::Red().full); + swipeView_->SetPosition(0, 0, Screen::GetInstance().GetWidth(), Screen::GetInstance().GetHeight()); + swipeView_->SetLoopState(true); + UIView* view1 = new UIView(); + view1->SetPosition(0, 0, initWidth, initHeight); + swipeView_->Add(view1); + UIView* view2 = new UIView(); + view2->SetPosition(0, 0, initWidth, initHeight); + swipeView_->Add(view2); + UIView* view3 = new UIView(); + view3->SetPosition(0, 0, initWidth, initHeight); + swipeView_->Add(view3); + + UIView* view = swipeView_->GetViewByIndex(1); + EXPECT_EQ(view2, view); + swipeView_->Remove(view1); + swipeView_->Remove(view2); + swipeView_->Remove(view3); + delete view1; + delete view2; + delete view3; +} + +/** + * @tc.name: Graphic_UISwipeView_Test_SetAlignMode_001 + * @tc.desc: Verify SetAlignMode function, equal. + * @tc.type: FUNC + * @tc.require: AR000EVTV4 + */ +HWTEST_F(UISwipeViewTest, Graphic_UISwipeView_Test_SetAlignMode_001, TestSize.Level0) +{ + if (swipeView_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + swipeView_->SetAlignMode(UISwipeView::ALIGN_LEFT); + EXPECT_EQ(swipeView_->GetAlignMode(), UISwipeView::ALIGN_LEFT); +} +} // namespace OHOS \ No newline at end of file diff --git a/test/unittest/components/ui_time_picker_unit_test.cpp b/test/unittest/components/ui_time_picker_unit_test.cpp new file mode 100755 index 0000000..c75c9f5 --- /dev/null +++ b/test/unittest/components/ui_time_picker_unit_test.cpp @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "components/ui_time_picker.h" +#include +#include + +using namespace testing::ext; +namespace OHOS { +class UITimePickerTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + static UITimePicker* timePicker_; +}; + +UITimePicker* UITimePickerTest::timePicker_ = nullptr; + +void UITimePickerTest::SetUpTestCase(void) +{ + if (timePicker_ == nullptr) { + timePicker_ = new UITimePicker(); + } +} + +void UITimePickerTest::TearDownTestCase(void) +{ + if (timePicker_ != nullptr) { + delete timePicker_; + timePicker_ = nullptr; + } +} +/** + * @tc.name: UITimePickerGetViewType_001 + * @tc.desc: Verify GetViewType function, equal. + * @tc.type: FUNC + * @tc.require: AR000EEMQ7 + */ +HWTEST_F(UITimePickerTest, UITimePickerGetViewType_001, TestSize.Level0) +{ + if (timePicker_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + EXPECT_EQ(timePicker_->GetViewType(), UI_TIME_PICKER); +} + +/** + * @tc.name: UITimePickerSetWidth_001 + * @tc.desc: Verify SetWidth function, equal. + * @tc.type: FUNC + * @tc.require: AR000EEMQ7 + */ +HWTEST_F(UITimePickerTest, UITimePickerSetWidth_001, TestSize.Level0) +{ + if (timePicker_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + const int16_t width = 50; + + timePicker_->SetWidth(width); + EXPECT_EQ(timePicker_->GetWidth(), width); +} + +/** + * @tc.name: UITimePickerSetHeight_001 + * @tc.desc: Verify SetHeight function, equal. + * @tc.type: FUNC + * @tc.require: AR000EEMQ7 + */ +HWTEST_F(UITimePickerTest, UITimePickerSetHeight_001, TestSize.Level0) +{ + if (timePicker_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + const int16_t height = 50; + + timePicker_->SetHeight(height); + EXPECT_EQ(timePicker_->GetHeight(), height); +} +} // namespace OHOS \ No newline at end of file diff --git a/test/unittest/components/ui_toggle_button_unit_test.cpp b/test/unittest/components/ui_toggle_button_unit_test.cpp new file mode 100755 index 0000000..d08f2f6 --- /dev/null +++ b/test/unittest/components/ui_toggle_button_unit_test.cpp @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "components/ui_toggle_button.h" + +#include +#include + +using namespace testing::ext; +namespace OHOS { +class UIToggleButtonTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + static UIToggleButton* toggleBtn_; +}; + +UIToggleButton* UIToggleButtonTest::toggleBtn_ = nullptr; + +void UIToggleButtonTest::SetUpTestCase(void) +{ + if (toggleBtn_ == nullptr) { + toggleBtn_ = new UIToggleButton(); + } +} + +void UIToggleButtonTest::TearDownTestCase(void) +{ + if (toggleBtn_ != nullptr) { + delete toggleBtn_; + toggleBtn_ = nullptr; + } +} + +/** + * @tc.name: UIToggleButtonGetViewType_001 + * @tc.desc: Verify GetViewType function. + * @tc.type: FUNC + * @tc.require: AR000DSMQA + */ +HWTEST_F(UIToggleButtonTest, UIToggleButtonGetViewType_001, TestSize.Level0) +{ + if (toggleBtn_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + EXPECT_EQ(toggleBtn_->GetViewType(), UI_TOGGLE_BUTTON); +} + +/** + * @tc.name: UIToggleButtonSetState_001 + * @tc.desc: Verify SetState function. + * @tc.type: FUNC + * @tc.require: AR000F4E5H + */ +HWTEST_F(UIToggleButtonTest, UIToggleButtonSetState_001, TestSize.Level0) +{ + if (toggleBtn_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + toggleBtn_->SetState(true); + EXPECT_EQ(toggleBtn_->GetState(), true); + + toggleBtn_->SetState(false); + EXPECT_EQ(toggleBtn_->GetState(), false); +} +} // namespace OHOS \ No newline at end of file diff --git a/test/unittest/components/ui_video_unit_test.cpp b/test/unittest/components/ui_video_unit_test.cpp new file mode 100755 index 0000000..3dfd423 --- /dev/null +++ b/test/unittest/components/ui_video_unit_test.cpp @@ -0,0 +1,457 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "components/ui_video.h" + +#include +#include + +using namespace testing::ext; +namespace OHOS { +namespace { + const int8_t STATE_PLAY = 1; + const int8_t STATE_PAUSE = 2; + const int8_t STATE_STOP = 3; + const int8_t STATE_COMPLETE = 4; + const int8_t STATE_REWIND = 5; + const int8_t STATE_ERROR = 6; + const int8_t STATE_INFO = 7; + const int8_t STATE_RESIZE = 8; +} +static int8_t g_state = 0; + +class TestVideoListener : public UIVideo::VideoPlayerListener { +public: + TestVideoListener() {} + ~TestVideoListener() {} + + void OnRewindToComplete() override + { + EXPECT_EQ(g_state, STATE_REWIND); + } + + void OnPlaybackPause() override + { + EXPECT_EQ(g_state, STATE_PAUSE); + } + + void OnPlaybackPlay() override + { + EXPECT_EQ(g_state, STATE_PLAY); + } + + void OnPlaybackStop() override + { + EXPECT_EQ(g_state, STATE_STOP); + } + + void OnPlaybackComplete() override + { + EXPECT_EQ(g_state, STATE_ERROR); + } + + void OnError(int32_t errorType, int32_t errorCode) override + { + EXPECT_EQ(g_state, STATE_COMPLETE); + } + + void OnInfo(int type, int extra) override + { + EXPECT_EQ(g_state, STATE_INFO); + } + + void OnVideoSizeChanged(int width, int height) override + { + EXPECT_EQ(g_state, STATE_RESIZE); + } +}; + +class UIVideoTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + static UIVideo* video_; + static TestVideoListener* listener_; + const char* videoPath_ = "/user/data/video.mp4"; +}; + +UIVideo* UIVideoTest::video_ = nullptr; +TestVideoListener* UIVideoTest::listener_ = nullptr; + +void UIVideoTest::SetUpTestCase(void) +{ + if (listener_ == nullptr) { + listener_ = new TestVideoListener(); + } +} + +void UIVideoTest::TearDownTestCase(void) +{ + if (video_ != nullptr) { + delete video_; + video_ = nullptr; + } + if (listener_ != nullptr) { + delete listener_; + listener_ = nullptr; + } +} + +/** + * @tc.name: UIVideoSetSrc_001 + * @tc.desc: Verify SetSrc function, abnormal situation. + * @tc.type: FUNC + * @tc.require: SR000F3PEN + */ +HWTEST_F(UIVideoTest, UIVideoSetSrc_001, TestSize.Level0) +{ + if (video_ == nullptr) { + video_ = new UIVideo(); + } + + const char* src = nullptr; + EXPECT_EQ(video_->SetSrc(src), false); + + src = "not exit path"; + EXPECT_EQ(video_->SetSrc(src), false); + EXPECT_EQ(video_->GetSrc(), src); + + video_->Reset(); + delete video_; + video_ = nullptr; +} + +/** + * @tc.name: VideoSetSrc_002 + * @tc.desc: Verify SetSrc function, normal situation. + * @tc.type: FUNC + * @tc.require: AR000F4E5Q + */ +HWTEST_F(UIVideoTest, UIVideoSetSrc_002, TestSize.Level0) +{ + if (video_ == nullptr) { + video_ = new UIVideo(); + } + + if (video_->SetSrc(videoPath_)) { + EXPECT_EQ(video_->GetSrc(), videoPath_); + } + video_->Reset(); + delete video_; + video_ = nullptr; +} + +/** + * @tc.name: VideoPrepare_001 + * @tc.desc: Verify Prepare function, abnormal situation. + * @tc.type: FUNC + * @tc.require: AR000F4E5Q + */ +HWTEST_F(UIVideoTest, UIVideoPrepare_001, TestSize.Level0) +{ + if (video_ == nullptr) { + video_ = new UIVideo(); + } + + video_->SetSrc(nullptr); + EXPECT_EQ(video_->Prepare(), false); + video_->SetSrc("not exist path"); + EXPECT_EQ(video_->Prepare(), false); + + video_->Reset(); + delete video_; + video_ = nullptr; +} + +/** + * @tc.name: VideoPrepare_002 + * @tc.desc: Verify Prepare function, normal situation. + * @tc.type: FUNC + * @tc.require: AR000F4E5Q + */ +HWTEST_F(UIVideoTest, UIVideoPrepare_002, TestSize.Level0) +{ + if (video_ == nullptr) { + video_ = new UIVideo(); + } + + if (!video_->SetSrc(videoPath_)) { + return; + } + if (listener_ != nullptr) { + video_->SetVideoPlayerListener(listener_); + } + + g_state = STATE_RESIZE; + EXPECT_EQ(video_->Prepare(), true); + + video_->Reset(); + delete video_; + video_ = nullptr; +} + +/** + * @tc.name: VideoPlay_001 + * @tc.desc: Verify Play function, abnormal situation. + * @tc.type: FUNC + * @tc.require: AR000F4E5Q + */ +HWTEST_F(UIVideoTest, UIVideoPlay_001, TestSize.Level0) +{ + if (video_ == nullptr) { + video_ = new UIVideo(); + } + + video_->SetSrc("not exist path"); + video_->Prepare(); + EXPECT_EQ(video_->Play(), false); + + video_->Reset(); + delete video_; + video_ = nullptr; +} + +/** + * @tc.name: VideoPlay_002 + * @tc.desc: Verify Play function, normal situation. + * @tc.type: FUNC + * @tc.require: AR000F4E5Q + */ +HWTEST_F(UIVideoTest, UIVideoPlay_002, TestSize.Level0) +{ + if (video_ == nullptr) { + video_ = new UIVideo(); + } + + if (!video_->SetSrc(videoPath_)) { + return; + } + if (listener_ != nullptr) { + video_->SetVideoPlayerListener(listener_); + } + + g_state = STATE_RESIZE; + video_->Prepare(); + + g_state = STATE_PLAY; + EXPECT_EQ(video_->Play(), true); + + g_state = STATE_PAUSE; + video_->Pause(); + + g_state = STATE_PLAY; + EXPECT_EQ(video_->Play(), true); + g_state = STATE_STOP; + video_->Stop(); + g_state = STATE_PLAY; + EXPECT_EQ(video_->Play(), false); + + video_->Reset(); + delete video_; + video_ = nullptr; +} + +/** + * @tc.name: VideoIsPlaying_001 + * @tc.desc: Verify IsPlaying function, equal. + * @tc.type: FUNC + * @tc.require: AR000F4E5Q + */ +HWTEST_F(UIVideoTest, UIVideoIsPlaying_001, TestSize.Level0) +{ + if (video_ == nullptr) { + video_ = new UIVideo(); + } + + if (!video_->SetSrc(videoPath_)) { + return; + } + video_->Prepare(); + EXPECT_EQ(video_->IsPlaying(), false); + + video_->Play(); + EXPECT_EQ(video_->IsPlaying(), true); + + video_->Reset(); + delete video_; + video_ = nullptr; +} + +/** + * @tc.name: VideoIsSingleLooping_001 + * @tc.desc: Verify IsSingleLooping function, equal. + * @tc.type: FUNC + * @tc.require: AR000F4E5Q + */ +HWTEST_F(UIVideoTest, UIVideoIsSingleLooping_001, TestSize.Level0) +{ + if (video_ == nullptr) { + video_ = new UIVideo(); + } + + if (!video_->SetSrc(videoPath_)) { + return; + } + video_->Prepare(); + video_->Play(); + EXPECT_EQ(video_->IsSingleLooping(), false); + video_->EnableSingleLooping(true); + EXPECT_EQ(video_->IsSingleLooping(), true); + + video_->EnableSingleLooping(false); + EXPECT_EQ(video_->IsSingleLooping(), false); + video_->Reset(); + delete video_; + video_ = nullptr; +} + +/** + * @tc.name: VideoRewind_001 + * @tc.desc: Verify Rewind function, equal. + * @tc.type: FUNC + * @tc.require: AR000F4E5Q + */ +HWTEST_F(UIVideoTest, UIVideoRewind_001, TestSize.Level0) +{ + if (video_ == nullptr) { + video_ = new UIVideo(); + } + + if (!video_->SetSrc(videoPath_)) { + return; + } + if (listener_ != nullptr) { + video_->SetVideoPlayerListener(listener_); + } + + g_state = STATE_RESIZE; + video_->Prepare(); + g_state = STATE_PLAY; + video_->Play(); + int64_t currentTime = 0; + video_->GetCurrentTime(currentTime); + int64_t rewindTime = currentTime + 3000; // 3000:rewind milli second + + g_state = STATE_REWIND; + video_->Rewind(rewindTime); + video_->GetCurrentTime(currentTime); + EXPECT_EQ(currentTime, rewindTime); + + video_->Reset(); + delete video_; + video_ = nullptr; +} + +/** + * @tc.name: VideoPause_001 + * @tc.desc: Verify Pause function, equal. + * @tc.type: FUNC + * @tc.require: AR000F4E5Q + */ +HWTEST_F(UIVideoTest, UIVideoPause_001, TestSize.Level0) +{ + if (video_ == nullptr) { + video_ = new UIVideo(); + } + + if (!video_->SetSrc(videoPath_)) { + return; + } + if (listener_ != nullptr) { + video_->SetVideoPlayerListener(listener_); + } + + g_state = STATE_RESIZE; + video_->Prepare(); + g_state = STATE_PLAY; + video_->Play(); + + g_state = STATE_PAUSE; + EXPECT_EQ(video_->Pause(), true); + + video_->Reset(); + EXPECT_EQ(video_->Pause(), false); + + video_->Reset(); + delete video_; + video_ = nullptr; +} + +/** + * @tc.name: VideoStop_001 + * @tc.desc: Verify Stop function, equal. + * @tc.type: FUNC + * @tc.require: AR000F4E5Q + */ +HWTEST_F(UIVideoTest, UIVideoStop_001, TestSize.Level0) +{ + if (video_ == nullptr) { + video_ = new UIVideo(); + } + + if (!video_->SetSrc(videoPath_)) { + return; + } + if (listener_ != nullptr) { + video_->SetVideoPlayerListener(listener_); + } + + g_state = STATE_RESIZE; + video_->Prepare(); + g_state = STATE_PLAY; + video_->Play(); + + g_state = STATE_STOP; + EXPECT_EQ(video_->Stop(), true); + + video_->Reset(); + EXPECT_EQ(video_->Stop(), false); + + video_->Reset(); + delete video_; + video_ = nullptr; +} + +/** + * @tc.name: VideoReset_001 + * @tc.desc: Verify Reset function, equal. + * @tc.type: FUNC + * @tc.require: AR000F4E5Q + */ +HWTEST_F(UIVideoTest, UIVideoReset_001, TestSize.Level0) +{ + if (video_ == nullptr) { + video_ = new UIVideo(); + } + + if (!video_->SetSrc(videoPath_)) { + return; + } + if (listener_ != nullptr) { + video_->SetVideoPlayerListener(listener_); + } + + g_state = STATE_RESIZE; + video_->Prepare(); + g_state = STATE_PLAY; + video_->Play(); + + EXPECT_EQ(video_->Reset(), true); + + video_->Reset(); + delete video_; + video_ = nullptr; +} +} // namespace OHOS \ No newline at end of file diff --git a/test/unittest/components/ui_view_group_unit_test.cpp b/test/unittest/components/ui_view_group_unit_test.cpp new file mode 100755 index 0000000..05fc896 --- /dev/null +++ b/test/unittest/components/ui_view_group_unit_test.cpp @@ -0,0 +1,161 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "components/ui_view_group.h" +#include +#include + +using namespace testing::ext; +namespace OHOS { +class UIViewGroupTest : public testing::Test { +public: + UIViewGroupTest() : viewGroup_(nullptr) {} + ~UIViewGroupTest() {} + static void SetUpTestCase(void) {} + static void TearDownTestCase(void) {} + void SetUp(void); + void TearDown(void); + UIViewGroup* viewGroup_; +}; + +void UIViewGroupTest::SetUp(void) +{ + if (viewGroup_ == nullptr) { + viewGroup_ = new UIViewGroup(); + } +} + +void UIViewGroupTest::TearDown(void) +{ + if (viewGroup_ != nullptr) { + delete viewGroup_; + viewGroup_ = nullptr; + } +} + +/** + * @tc.name: UIViewGroupAdd_001 + * @tc.desc: Verify Add function. + * @tc.type: FUNC + * @tc.require: AR000EEMQF + */ +HWTEST_F(UIViewGroupTest, UIViewGroupAdd_001, TestSize.Level0) +{ + if (viewGroup_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + UIView* view = new UIView(); + if (view == nullptr) { + EXPECT_EQ(1, 0); + return; + } + viewGroup_->Add(view); + EXPECT_EQ(view, viewGroup_->GetChildrenHead()); + EXPECT_EQ(view->GetParent(), viewGroup_); + + delete view; +} + +/** + * @tc.name: UIViewGroupInsert_001 + * @tc.desc: Verify Insert function. + * @tc.type: FUNC + * @tc.require: AR000EEMQF + */ +HWTEST_F(UIViewGroupTest, UIViewGroupInsert_001, TestSize.Level0) +{ + if (viewGroup_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + UIView* preView = new UIView(); + if (preView == nullptr) { + EXPECT_EQ(1, 0); + return; + } + UIView* view = new UIView(); + + viewGroup_->Add(preView); + viewGroup_->Insert(preView, view); + EXPECT_EQ(view, preView->GetNextSibling()); + + delete preView; + delete view; +} + +/** + * @tc.name: UIViewGroupRemove_001 + * @tc.desc: Verify Remove function. + * @tc.type: FUNC + * @tc.require: AR000EEMQF + */ +HWTEST_F(UIViewGroupTest, UIViewGroupRemove_001, TestSize.Level0) +{ + if (viewGroup_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + UIView* view = new UIView(); + if (view == nullptr) { + EXPECT_EQ(1, 0); + return; + } + viewGroup_->Add(view); + viewGroup_->Remove(view); + EXPECT_EQ(nullptr, viewGroup_->GetChildrenHead()); + EXPECT_EQ(nullptr, view->GetParent()); + + delete view; +} + +/** + * @tc.name: UIViewGroupRemoveAll_001 + * @tc.desc: Verify RemoveAll function. + * @tc.type: FUNC + * @tc.require: AR000EEMQF + */ +HWTEST_F(UIViewGroupTest, UIViewGroupRemoveAll_001, TestSize.Level0) +{ + if (viewGroup_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + UIView* view = new UIView(); + UIView* view2 = new UIView(); + + viewGroup_->Add(view); + viewGroup_->RemoveAll(); + EXPECT_EQ(nullptr, viewGroup_->GetChildrenHead()); + + delete view; + delete view2; +} + +/** + * @tc.name: UIViewGroupGetViewType_001 + * @tc.desc: Verify GetViewType function. + * @tc.type: FUNC + * @tc.require: AR000EEMQF + */ +HWTEST_F(UIViewGroupTest, UIViewGroupGetViewType_001, TestSize.Level0) +{ + if (viewGroup_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + EXPECT_EQ(viewGroup_->GetViewType(), UI_VIEW_GROUP); +} +} // namespace OHOS \ No newline at end of file diff --git a/test/unittest/components/ui_view_unit_test.cpp b/test/unittest/components/ui_view_unit_test.cpp new file mode 100755 index 0000000..ac10310 --- /dev/null +++ b/test/unittest/components/ui_view_unit_test.cpp @@ -0,0 +1,1040 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "components/ui_view_group.h" + +#include +#include + +using namespace testing::ext; +namespace OHOS { +namespace { + const int16_t POS_X = 10; + const int16_t POS_Y = 20; + const int16_t DEFAULE_WIDTH = 100; + const int16_t DEFAULE_HEIGHT = 100; + const int16_t BUTTON_WIDTH = 20; + const int16_t BUTTON_HEIGHT = 20; + const float POS_X_PERCENT = 0.1; + const float POS_Y_PERCENT = 0.2; + const float DEFAULT_WIDTH_PERCENT = 0.3; + const float DEFAULT_HEIGHT_PERCENT = 0.4; + const float INVAILD_PERCENT_ZERO = 0.0f; + const float INVAILD_PERCENT_ONE = 1.0f; + const int16_t DEFAULE_ANGLE = 45; + const Vector2 VIEW_CENTER = {50, 50}; + const Vector2 SCALE_VALUE = {0.5f, 0.5f}; + const Vector2 POLYGON1 = {0, 0}; + const Vector2 POLYGON2 = {70, 70}; + const Vector2 POLYGON3 = {0, 140}; + const Vector2 POLYGON4 = {-70, 70}; +} + +class UIViewTest : public testing::Test { +public: + UIViewTest() : view_(nullptr) {} + virtual ~UIViewTest() {} + static void SetUpTestCase() {} + static void TearDownTestCase() {} + void SetUp(); + void TearDown(); + UIView* view_; +}; + +void UIViewTest::SetUp() +{ + if (view_ == nullptr) { + view_ = new UIView(); + } +} + +void UIViewTest::TearDown() +{ + if (view_ != nullptr) { + delete view_; + view_ = nullptr; + } +} + +/** + * @tc.name: UIViewSetOnDragListener_001 + * @tc.desc: Verify SetOnDragListener function, equal. + * @tc.type: FUNC + * @tc.require: AR000EEMQF + */ +HWTEST_F(UIViewTest, UIViewSetOnDragListener_001, TestSize.Level0) +{ + if (view_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + UIView::OnDragListener* listener = new UIView::OnDragListener(); + view_->SetOnDragListener(listener); + EXPECT_EQ(view_->GetOnDragListener(), listener); + delete listener; +} + +/** + * @tc.name: UIViewSetOnClickListener_001 + * @tc.desc: Verify SetOnClickListener function, equal. + * @tc.type: FUNC + * @tc.require: AR000EEMQF + */ +HWTEST_F(UIViewTest, UIViewSetOnClickListener_001, TestSize.Level0) +{ + if (view_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + UIView::OnClickListener* listener = new UIView::OnClickListener(); + view_->SetOnClickListener(listener); + EXPECT_EQ(view_->GetOnClickListener(), listener); + delete listener; +} + +/** + * @tc.name: UIViewSetOnLongPressListener_001 + * @tc.desc: Verify SetOnLongPressListener function, equal. + * @tc.type: FUNC + * @tc.require: AR000EEMQF + */ +HWTEST_F(UIViewTest, UIViewSetOnLongPressListener_001, TestSize.Level0) +{ + if (view_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + UIView::OnLongPressListener* listener = new UIView::OnLongPressListener(); + view_->SetOnLongPressListener(listener); + EXPECT_EQ(view_->GetOnLongPressListener(), listener); + delete listener; +} + +/** + * @tc.name: UIViewSetOnTouchListener_001 + * @tc.desc: Verify SetOnTouchListener function, equal. + * @tc.type: FUNC + * @tc.require: AR000EEMQF + */ +HWTEST_F(UIViewTest, UIViewSetOnTouchListener_001, TestSize.Level0) +{ + if (view_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + UIView::OnTouchListener* listener = new UIView::OnTouchListener(); + view_->SetOnTouchListener(listener); + EXPECT_EQ(view_->GetTouchListener(), listener); + delete listener; +} + +/** + * @tc.name: UIViewSetParent_001 + * @tc.desc: Verify SetParent function, equal. + * @tc.type: FUNC + * @tc.require: AR000EEMQF + */ +HWTEST_F(UIViewTest, UIViewSetParent_001, TestSize.Level0) +{ + if (view_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + UIViewGroup* viewGroup = new UIViewGroup(); + if (viewGroup == nullptr) { + EXPECT_NE(0, 0); + return; + } + view_->SetParent(viewGroup); + EXPECT_EQ(view_->GetParent(), viewGroup); + + delete viewGroup; +} + +/** + * @tc.name: UIViewSetNextSibling_001 + * @tc.desc: Verify SetNextSibling function, equal. + * @tc.type: FUNC + * @tc.require: AR000EEMQF + */ +HWTEST_F(UIViewTest, UIViewSetNextSibling_001, TestSize.Level0) +{ + if (view_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + UIView* tempView = new UIView(); + if (tempView == nullptr) { + EXPECT_NE(0, 0); + return; + } + view_->SetNextSibling(tempView); + EXPECT_EQ(view_->GetNextSibling(), tempView); + + delete tempView; +} + +/** + * @tc.name: UIViewSetVisible_001 + * @tc.desc: Verify SetVisible function, equal. + * @tc.type: FUNC + * @tc.require: AR000EEMQF + */ +HWTEST_F(UIViewTest, UIViewSetVisible_001, TestSize.Level0) +{ + if (view_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + view_->SetVisible(true); + EXPECT_EQ(view_->IsVisible(), true); +} + +/** + * @tc.name: UIViewSetTouchable_001 + * @tc.desc: Verify SetTouchable function, equal. + * @tc.type: FUNC + * @tc.require: AR000EEMQF + */ +HWTEST_F(UIViewTest, UIViewSetTouchable_001, TestSize.Level0) +{ + if (view_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + view_->SetTouchable(true); + EXPECT_EQ(view_->IsTouchable(), true); +} + +/** + * @tc.name: UIViewSetDraggable_001 + * @tc.desc: Verify SetDraggable function, equal. + * @tc.type: FUNC + * @tc.require: AR000EEMQF + */ +HWTEST_F(UIViewTest, UIViewSetDraggable_001, TestSize.Level0) +{ + if (view_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + view_->SetDraggable(true); + EXPECT_EQ(view_->IsDraggable(), true); +} + +/** + * @tc.name: UIViewSetDragParentInstead_001 + * @tc.desc: Verify SetDragParentInstead function, equal. + * @tc.type: FUNC + * @tc.require: AR000EEMQF + */ +HWTEST_F(UIViewTest, UIViewSetDragParentInstead_001, TestSize.Level0) +{ + if (view_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + view_->SetDragParentInstead(true); + EXPECT_EQ(view_->IsDragParentInstead(), true); +} + +/** + * @tc.name: UIViewResizeVisibleArea_001 + * @tc.desc: Verify ResizeVisibleArea function, equal. + * @tc.type: FUNC + * @tc.require: AR000EEMQF + */ +HWTEST_F(UIViewTest, UIViewResizeVisibleArea_001, TestSize.Level0) +{ + if (view_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + view_->ResizeVisibleArea(POS_X, POS_Y, DEFAULE_WIDTH, DEFAULE_HEIGHT); + + EXPECT_EQ(view_->GetVisibleRect().GetWidth(), DEFAULE_WIDTH); + EXPECT_EQ(view_->GetVisibleRect().GetHeight(), DEFAULE_HEIGHT); +} + +/** + * @tc.name: UIViewSetWidth_001 + * @tc.desc: Verify SetWidth function, equal. + * @tc.type: FUNC + * @tc.require: AR000EEMQF + */ +HWTEST_F(UIViewTest, UIViewSetWidth_001, TestSize.Level0) +{ + if (view_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + view_->SetWidth(0); + EXPECT_EQ(view_->GetWidth(), 0); + view_->SetWidth(DEFAULE_WIDTH); + EXPECT_EQ(view_->GetWidth(), DEFAULE_WIDTH); +} + +/** + * @tc.name: UIViewSetHeight_001 + * @tc.desc: Verify SetHeight function, equal. + * @tc.type: FUNC + * @tc.require: AR000EEMQF + */ +HWTEST_F(UIViewTest, UIViewSetHeight_001, TestSize.Level0) +{ + if (view_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + view_->SetHeight(0); + EXPECT_EQ(view_->GetHeight(), 0); + view_->SetHeight(DEFAULE_HEIGHT); + EXPECT_EQ(view_->GetHeight(), DEFAULE_HEIGHT); +} + +/** + * @tc.name: UIViewResize_001 + * @tc.desc: Verify Resize function, equal. + * @tc.type: FUNC + * @tc.require: AR000EEMQF + */ +HWTEST_F(UIViewTest, UIViewResize_001, TestSize.Level0) +{ + if (view_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + view_->Resize(0, 0); + EXPECT_EQ(view_->GetHeight(), 0); + EXPECT_EQ(view_->GetWidth(), 0); + view_->Resize(DEFAULE_WIDTH, DEFAULE_HEIGHT); + EXPECT_EQ(view_->GetHeight(), DEFAULE_HEIGHT); + EXPECT_EQ(view_->GetWidth(), DEFAULE_WIDTH); +} + +/** + * @tc.name: UIViewSetX_001 + * @tc.desc: Verify SetX function, equal. + * @tc.type: FUNC + * @tc.require: AR000EEMQF + */ +HWTEST_F(UIViewTest, UIViewSetX_001, TestSize.Level0) +{ + if (view_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + view_->SetX(0); + EXPECT_EQ(view_->GetX(), 0); + view_->SetX(POS_X); + EXPECT_EQ(view_->GetX(), POS_X); +} + +/** + * @tc.name: UIViewSetY_001 + * @tc.desc: Verify SetY function, equal. + * @tc.type: FUNC + * @tc.require: AR000EEMQF + */ +HWTEST_F(UIViewTest, UIViewSetY_001, TestSize.Level0) +{ + if (view_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + view_->SetY(0); + EXPECT_EQ(view_->GetY(), 0); + view_->SetY(POS_Y); + EXPECT_EQ(view_->GetY(), POS_Y); +} + +/** + * @tc.name: UIViewSetPosition_001 + * @tc.desc: Verify SetPosition function, equal. + * @tc.type: FUNC + * @tc.require: AR000EEMQF + */ +HWTEST_F(UIViewTest, UIViewSetPosition_001, TestSize.Level0) +{ + if (view_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + view_->SetPosition(0, 0); + EXPECT_EQ(view_->GetX(), 0); + EXPECT_EQ(view_->GetY(), 0); + view_->SetPosition(POS_X, POS_Y); + EXPECT_EQ(view_->GetX(), POS_X); + EXPECT_EQ(view_->GetY(), POS_Y); +} + +/** + * @tc.name: UIViewSetPosition_002 + * @tc.desc: Verify SetPosition function, equal. + * @tc.type: FUNC + * @tc.require: AR000EEMQF + */ +HWTEST_F(UIViewTest, UIViewSetPosition_002, TestSize.Level0) +{ + if (view_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + view_->SetPosition(0, 0, 0, 0); + EXPECT_EQ(view_->GetHeight(), 0); + EXPECT_EQ(view_->GetWidth(), 0); + EXPECT_EQ(view_->GetX(), 0); + EXPECT_EQ(view_->GetY(), 0); + view_->SetPosition(POS_X, POS_Y, DEFAULE_WIDTH, DEFAULE_HEIGHT); + EXPECT_EQ(view_->GetHeight(), DEFAULE_HEIGHT); + EXPECT_EQ(view_->GetWidth(), DEFAULE_WIDTH); + EXPECT_EQ(view_->GetX(), POS_X); + EXPECT_EQ(view_->GetY(), POS_Y); +} + +/** + * @tc.name: UIViewSetWidthPercent_001 + * @tc.desc: Verify SetWidthPercent function, equal. + * @tc.type: FUNC + * @tc.require: SR000F3PE8 + */ +HWTEST_F(UIViewTest, UIViewSetWidthPercent_001, TestSize.Level0) +{ + if (view_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + view_->SetPosition(POS_X, POS_Y, DEFAULE_WIDTH, DEFAULE_HEIGHT); + EXPECT_EQ(view_->GetHeight(), DEFAULE_HEIGHT); + EXPECT_EQ(view_->GetWidth(), DEFAULE_WIDTH); + EXPECT_EQ(view_->GetX(), POS_X); + EXPECT_EQ(view_->GetY(), POS_Y); + + // Not has parent, SetWidthPercent failed + view_->SetWidthPercent(POS_X_PERCENT); + EXPECT_EQ(view_->GetWidth(), DEFAULE_WIDTH); + + // Parent does not SetWidth, view SetWidthPercent failed + UIViewGroup* viewGroup = new UIViewGroup(); + viewGroup->Add(view_); + view_->SetWidthPercent(POS_X_PERCENT); + EXPECT_EQ(view_->GetWidth(), DEFAULE_WIDTH); + + viewGroup->SetWidth(DEFAULE_WIDTH); + viewGroup->SetHeight(DEFAULE_HEIGHT); + + // Input invaild percent, SetWidthPercent failed + view_->SetWidthPercent(INVAILD_PERCENT_ZERO); + EXPECT_EQ(view_->GetWidth(), DEFAULE_WIDTH); + view_->SetWidthPercent(INVAILD_PERCENT_ONE); + EXPECT_EQ(view_->GetWidth(), DEFAULE_WIDTH); + + view_->SetWidthPercent(POS_X_PERCENT); + EXPECT_EQ(view_->GetWidth(), (int16_t)(DEFAULE_WIDTH * POS_X_PERCENT)); + + delete viewGroup; +} + +/** + * @tc.name: UIViewSetHeightPercent_001 + * @tc.desc: Verify SetHeightPercent function, equal. + * @tc.type: FUNC + * @tc.require: AR000F4770 + */ +HWTEST_F(UIViewTest, UIViewSetHeightPercent_001, TestSize.Level0) +{ + if (view_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + view_->SetPosition(POS_X, POS_Y, DEFAULE_WIDTH, DEFAULE_HEIGHT); + EXPECT_EQ(view_->GetHeight(), DEFAULE_HEIGHT); + EXPECT_EQ(view_->GetWidth(), DEFAULE_WIDTH); + EXPECT_EQ(view_->GetX(), POS_X); + EXPECT_EQ(view_->GetY(), POS_Y); + + // Not has parent, SetHeightPercent failed + view_->SetHeightPercent(POS_Y_PERCENT); + EXPECT_EQ(view_->GetHeight(), DEFAULE_HEIGHT); + + // Parent does not SetHeight, view SetHeightPercent failed + UIViewGroup* viewGroup = new UIViewGroup(); + viewGroup->Add(view_); + view_->SetHeightPercent(POS_Y_PERCENT); + EXPECT_EQ(view_->GetHeight(), DEFAULE_HEIGHT); + + viewGroup->SetWidth(DEFAULE_WIDTH); + viewGroup->SetHeight(DEFAULE_HEIGHT); + + // Input invaild percent, SetHeightPercent failed + view_->SetHeightPercent(INVAILD_PERCENT_ZERO); + EXPECT_EQ(view_->GetHeight(), DEFAULE_HEIGHT); + view_->SetHeightPercent(INVAILD_PERCENT_ONE); + EXPECT_EQ(view_->GetHeight(), DEFAULE_HEIGHT); + + view_->SetHeightPercent(POS_Y_PERCENT); + EXPECT_EQ(view_->GetHeight(), (int16_t)(DEFAULE_HEIGHT * POS_Y_PERCENT)); + + delete viewGroup; +} + +/** + * @tc.name: UIViewResizePercent_001 + * @tc.desc: Verify ResizePercent function, equal. + * @tc.type: FUNC + * @tc.require: AR000F4770 + */ +HWTEST_F(UIViewTest, UIViewResizePercent_001, TestSize.Level0) +{ + if (view_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + view_->SetPosition(POS_X, POS_Y, DEFAULE_WIDTH, DEFAULE_HEIGHT); + EXPECT_EQ(view_->GetHeight(), DEFAULE_HEIGHT); + EXPECT_EQ(view_->GetWidth(), DEFAULE_WIDTH); + EXPECT_EQ(view_->GetX(), POS_X); + EXPECT_EQ(view_->GetY(), POS_Y); + + // Not has parent, ResizePercent failed + view_->ResizePercent(POS_X_PERCENT, POS_Y_PERCENT); + EXPECT_EQ(view_->GetHeight(), DEFAULE_HEIGHT); + EXPECT_EQ(view_->GetWidth(), DEFAULE_WIDTH); + + // Parent does not SetWidth and SetHeight, view ResizePercent failed + UIViewGroup* viewGroup = new UIViewGroup(); + viewGroup->Add(view_); + view_->ResizePercent(POS_X_PERCENT, POS_Y_PERCENT); + EXPECT_EQ(view_->GetHeight(), DEFAULE_HEIGHT); + EXPECT_EQ(view_->GetWidth(), DEFAULE_WIDTH); + + viewGroup->SetWidth(DEFAULE_WIDTH); + viewGroup->SetHeight(DEFAULE_HEIGHT); + + // Input invaild percent, ResizePercent failed + view_->ResizePercent(INVAILD_PERCENT_ZERO, POS_Y_PERCENT); + EXPECT_EQ(view_->GetHeight(), DEFAULE_HEIGHT); + EXPECT_EQ(view_->GetWidth(), DEFAULE_WIDTH); + view_->ResizePercent(POS_X_PERCENT, INVAILD_PERCENT_ONE); + EXPECT_EQ(view_->GetHeight(), DEFAULE_HEIGHT); + EXPECT_EQ(view_->GetWidth(), DEFAULE_WIDTH); + + view_->ResizePercent(POS_X_PERCENT, POS_Y_PERCENT); + EXPECT_EQ(view_->GetHeight(), (int16_t)(DEFAULE_HEIGHT * POS_Y_PERCENT)); + EXPECT_EQ(view_->GetWidth(), (int16_t)(DEFAULE_WIDTH * POS_X_PERCENT)); + + delete viewGroup; +} + +/** + * @tc.name: UIViewSetXPercent_001 + * @tc.desc: Verify SetXPercent function, equal. + * @tc.type: FUNC + * @tc.require: AR000F4770 + */ +HWTEST_F(UIViewTest, UIViewSetXPercent_001, TestSize.Level0) +{ + if (view_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + view_->SetPosition(POS_X, POS_Y, DEFAULE_WIDTH, DEFAULE_HEIGHT); + EXPECT_EQ(view_->GetHeight(), DEFAULE_HEIGHT); + EXPECT_EQ(view_->GetWidth(), DEFAULE_WIDTH); + EXPECT_EQ(view_->GetX(), POS_X); + EXPECT_EQ(view_->GetY(), POS_Y); + + // Not has parent, SetXPercent failed + view_->SetXPercent(POS_X_PERCENT); + EXPECT_EQ(view_->GetX(), POS_X); + + // Parent does not SetWidth, view SetXPercent failed + UIViewGroup* viewGroup = new UIViewGroup(); + viewGroup->Add(view_); + view_->SetXPercent(POS_X_PERCENT); + EXPECT_EQ(view_->GetX(), POS_X); + + viewGroup->SetWidth(DEFAULE_WIDTH); + viewGroup->SetHeight(DEFAULE_HEIGHT); + + // Input invaild percent, SetXPercent failed + view_->SetXPercent(INVAILD_PERCENT_ZERO); + EXPECT_EQ(view_->GetX(), POS_X); + view_->SetXPercent(INVAILD_PERCENT_ONE); + EXPECT_EQ(view_->GetX(), POS_X); + + view_->SetXPercent(POS_X_PERCENT); + EXPECT_EQ(view_->GetX(), (int16_t)(POS_X_PERCENT * DEFAULE_WIDTH)); + + delete viewGroup; +} + +/** + * @tc.name: UIViewSetYPercent_001 + * @tc.desc: Verify SetYPercent function, equal. + * @tc.type: FUNC + * @tc.require: AR000F4770 + */ +HWTEST_F(UIViewTest, UIViewSetYPercent_001, TestSize.Level0) +{ + if (view_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + view_->SetPosition(POS_X, POS_Y, DEFAULE_WIDTH, DEFAULE_HEIGHT); + EXPECT_EQ(view_->GetHeight(), DEFAULE_HEIGHT); + EXPECT_EQ(view_->GetWidth(), DEFAULE_WIDTH); + EXPECT_EQ(view_->GetX(), POS_X); + EXPECT_EQ(view_->GetY(), POS_Y); + + // Not has parent, SetYPercent failed + view_->SetYPercent(POS_Y_PERCENT); + EXPECT_EQ(view_->GetY(), POS_Y); + + // Parent does not SetHeight, view SetYPercent failed + UIViewGroup* viewGroup = new UIViewGroup(); + viewGroup->Add(view_); + view_->SetYPercent(POS_Y_PERCENT); + EXPECT_EQ(view_->GetY(), POS_Y); + + viewGroup->SetWidth(DEFAULE_WIDTH); + viewGroup->SetHeight(DEFAULE_HEIGHT); + + // Input invaild percent, SetYPercent failed + view_->SetYPercent(INVAILD_PERCENT_ZERO); + EXPECT_EQ(view_->GetY(), POS_Y); + view_->SetYPercent(INVAILD_PERCENT_ONE); + EXPECT_EQ(view_->GetY(), POS_Y); + + view_->SetYPercent(POS_Y_PERCENT); + EXPECT_EQ(view_->GetY(), (int16_t)(POS_Y_PERCENT * DEFAULE_HEIGHT)); + + delete viewGroup; +} + +/** + * @tc.name: UIViewSetPositionPercent_001 + * @tc.desc: Verify SetPositionPercent function, equal. + * @tc.type: FUNC + * @tc.require: AR000F4770 + */ +HWTEST_F(UIViewTest, UIViewSetPositionPercent_001, TestSize.Level0) +{ + if (view_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + view_->SetPosition(POS_X, POS_Y, DEFAULE_WIDTH, DEFAULE_HEIGHT); + EXPECT_EQ(view_->GetHeight(), DEFAULE_HEIGHT); + EXPECT_EQ(view_->GetWidth(), DEFAULE_WIDTH); + EXPECT_EQ(view_->GetX(), POS_X); + EXPECT_EQ(view_->GetY(), POS_Y); + + // Not has parent, SetPositionPercent failed + view_->SetPositionPercent(POS_X_PERCENT, POS_Y_PERCENT); + EXPECT_EQ(view_->GetX(), POS_X); + EXPECT_EQ(view_->GetY(), POS_Y); + + // Parent does not SetWidth, view SetPositionPercent failed + UIViewGroup* viewGroup = new UIViewGroup(); + viewGroup->Add(view_); + view_->SetPositionPercent(POS_X_PERCENT, POS_Y_PERCENT); + EXPECT_EQ(view_->GetX(), POS_X); + EXPECT_EQ(view_->GetY(), POS_Y); + + viewGroup->SetWidth(DEFAULE_WIDTH); + viewGroup->SetHeight(DEFAULE_HEIGHT); + + // Input invaild percent, SetPositionPercent failed + view_->SetPositionPercent(INVAILD_PERCENT_ZERO, INVAILD_PERCENT_ONE); + EXPECT_EQ(view_->GetX(), POS_X); + EXPECT_EQ(view_->GetY(), POS_Y); + + view_->SetPositionPercent(POS_X_PERCENT, POS_Y_PERCENT); + EXPECT_EQ(view_->GetX(), (int16_t)(POS_X_PERCENT * DEFAULE_WIDTH)); + EXPECT_EQ(view_->GetY(), (int16_t)(POS_Y_PERCENT * DEFAULE_HEIGHT)); + + delete viewGroup; +} + +/** + * @tc.name: Graphic_UIView_Test_SetPositionPercent_002 + * @tc.desc: Verify SetPositionPercent function, equal. + * @tc.type: FUNC + * @tc.require: AR000F4770 + */ +HWTEST_F(UIViewTest, UIViewSetPositionPercent_002, TestSize.Level0) +{ + if (view_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + view_->SetPosition(POS_X, POS_Y, DEFAULE_WIDTH, DEFAULE_HEIGHT); + EXPECT_EQ(view_->GetHeight(), DEFAULE_HEIGHT); + EXPECT_EQ(view_->GetWidth(), DEFAULE_WIDTH); + EXPECT_EQ(view_->GetX(), POS_X); + EXPECT_EQ(view_->GetY(), POS_Y); + + // Not has parent, SetPositionPercent failed + view_->SetPositionPercent(POS_X_PERCENT, POS_Y_PERCENT, DEFAULT_WIDTH_PERCENT, DEFAULT_HEIGHT_PERCENT); + EXPECT_EQ(view_->GetHeight(), DEFAULE_HEIGHT); + EXPECT_EQ(view_->GetWidth(), DEFAULE_WIDTH); + EXPECT_EQ(view_->GetX(), POS_X); + EXPECT_EQ(view_->GetY(), POS_Y); + + // Parent does not SetWidth, view SetPositionPercent failed + UIViewGroup* viewGroup = new UIViewGroup(); + viewGroup->Add(view_); + view_->SetPositionPercent(POS_X_PERCENT, POS_Y_PERCENT, DEFAULT_WIDTH_PERCENT, DEFAULT_HEIGHT_PERCENT); + EXPECT_EQ(view_->GetHeight(), DEFAULE_HEIGHT); + EXPECT_EQ(view_->GetWidth(), DEFAULE_WIDTH); + EXPECT_EQ(view_->GetX(), POS_X); + EXPECT_EQ(view_->GetY(), POS_Y); + + viewGroup->SetWidth(DEFAULE_WIDTH); + viewGroup->SetHeight(DEFAULE_HEIGHT); + + // Input invaild percent, SetPositionPercent failed + view_->SetPositionPercent(INVAILD_PERCENT_ZERO, INVAILD_PERCENT_ONE, DEFAULT_WIDTH_PERCENT, DEFAULT_HEIGHT_PERCENT); + EXPECT_EQ(view_->GetHeight(), DEFAULE_HEIGHT); + EXPECT_EQ(view_->GetWidth(), DEFAULE_WIDTH); + EXPECT_EQ(view_->GetX(), POS_X); + EXPECT_EQ(view_->GetY(), POS_Y); + + + view_->SetPositionPercent(POS_X_PERCENT, POS_Y_PERCENT, DEFAULT_WIDTH_PERCENT, DEFAULT_HEIGHT_PERCENT); + EXPECT_EQ(view_->GetHeight(), (int16_t)(DEFAULE_HEIGHT * DEFAULT_HEIGHT_PERCENT)); + EXPECT_EQ(view_->GetWidth(), (int16_t)(DEFAULE_WIDTH * DEFAULT_WIDTH_PERCENT)); + EXPECT_EQ(view_->GetX(), (int16_t)(POS_X_PERCENT * DEFAULE_WIDTH)); + EXPECT_EQ(view_->GetY(), (int16_t)(POS_Y_PERCENT * DEFAULE_HEIGHT)); + + delete viewGroup; +} + +/** + * @tc.name: UIViewSetViewId_001 + * @tc.desc: Verify SetViewId function, equal. + * @tc.type: FUNC + * @tc.require: AR000EEMQF + */ +HWTEST_F(UIViewTest, UIViewSetViewId_001, TestSize.Level0) +{ + if (view_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + const char* id = "graphic_unittest_view"; + + view_->SetViewId(id); + EXPECT_EQ(memcmp(view_->GetViewId(), id, strlen(id)), 0); +} + +/** + * @tc.name: UIViewSetViewIndex_001 + * @tc.desc: Verify SetViewIndex function, equal. + * @tc.type: FUNC + * @tc.require: AR000EEMQF + */ +HWTEST_F(UIViewTest, UIViewSetViewIndex_001, TestSize.Level0) +{ + if (view_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + int16_t index = 1; + + view_->SetViewIndex(index); + EXPECT_EQ(view_->GetViewIndex(), index); +} + +/** + * @tc.name: UIViewGetViewType_001 + * @tc.desc: Verify GetViewType function, equal. + * @tc.type: FUNC + * @tc.require: AR000EEMQF + */ +HWTEST_F(UIViewTest, UIViewGetViewType_001, TestSize.Level0) +{ + if (view_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + EXPECT_EQ(view_->GetViewType(), UI_NUMBER_MAX); +} + +/** + * @tc.name: UIViewSetOpaScale_001 + * @tc.desc: Verify SetOpaScale function, equal. + * @tc.type: FUNC + * @tc.require: AR000F4E5D + */ +HWTEST_F(UIViewTest, UIViewSetOpaScale_001, TestSize.Level0) +{ + if (view_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + uint8_t opaScale = OPA_OPAQUE; + + view_->SetOpaScale(OPA_OPAQUE); + EXPECT_EQ(view_->GetOpaScale(), OPA_OPAQUE); +} + +/** + * @tc.name: UIViewSetOpaScale_002 + * @tc.desc: Verify SetOpaScale function, equal. + * @tc.type: FUNC + * @tc.require: SR000F3PEB + */ +HWTEST_F(UIViewTest, UIViewSetOpaScale_002, TestSize.Level0) +{ + if (view_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + uint8_t opaScale = OPA_OPAQUE; + + view_->SetOpaScale(OPA_OPAQUE); + view_->SetStyle(STYLE_BACKGROUND_OPA, opaScale >> 1); + view_->SetStyle(STYLE_BORDER_OPA, opaScale >> 1); + EXPECT_EQ(view_->GetOpaScale(), OPA_OPAQUE); +} + +/** + * @tc.name: UIViewSetStyle_001 + * @tc.desc: Verify SetStyle function, equal. + * @tc.type: FUNC + * @tc.require: AR000EEMQF + */ +HWTEST_F(UIViewTest, UIViewSetStyle_001, TestSize.Level0) +{ + if (view_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + Style style; + style.borderOpa_ = OPA_OPAQUE; + view_->SetStyle(style); + EXPECT_EQ(view_->GetStyleConst().borderOpa_, OPA_OPAQUE); + view_->SetStyle(STYLE_LINE_OPA, OPA_OPAQUE); + EXPECT_EQ(view_->GetStyle(STYLE_LINE_OPA), OPA_OPAQUE); +} + +/** + * @tc.name: UIViewLayoutOfParent_001 + * @tc.desc: Verify LayoutOfParent function, equal. + * @tc.type: FUNC + * @tc.require: AR000EEMQF + */ +HWTEST_F(UIViewTest, UIViewLayoutOfParent_001, TestSize.Level0) +{ + if (view_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + UIViewGroup* viewGroup = new UIViewGroup(); + viewGroup->SetPosition(0, 0, DEFAULE_WIDTH, DEFAULE_HEIGHT); + view_->SetPosition(POS_X, POS_Y, BUTTON_WIDTH, BUTTON_HEIGHT); + viewGroup->Add(view_); + int16_t centerX = (DEFAULE_WIDTH- BUTTON_WIDTH) / 2; // 2: center of x; + int16_t centerY = (DEFAULE_HEIGHT- BUTTON_HEIGHT) / 2; // 2: center of y; + EXPECT_EQ(view_->GetX(), POS_X); + EXPECT_EQ(view_->GetY(), POS_Y); + view_->LayoutCenterOfParent(); + EXPECT_EQ(view_->GetX(), centerX); + EXPECT_EQ(view_->GetY(), centerY); + view_->LayoutLeftOfParent(); + EXPECT_EQ(view_->GetX(), 0); + EXPECT_EQ(view_->GetY(), centerY); + view_->LayoutRightOfParent(); + EXPECT_EQ(view_->GetX(), DEFAULE_WIDTH- BUTTON_WIDTH); + EXPECT_EQ(view_->GetY(), centerY); + view_->LayoutTopOfParent(); + EXPECT_EQ(view_->GetX(), DEFAULE_WIDTH- BUTTON_WIDTH); + EXPECT_EQ(view_->GetY(), 0); + view_->LayoutBottomOfParent(); + EXPECT_EQ(view_->GetX(), DEFAULE_WIDTH- BUTTON_WIDTH); + EXPECT_EQ(view_->GetY(), DEFAULE_HEIGHT- BUTTON_HEIGHT); + + delete viewGroup; +} + +/** + * @tc.name: UIViewAlignToSibling_001 + * @tc.desc: Verify AlignToSibling function, equal. + * @tc.type: FUNC + * @tc.require: AR000EEMQF + */ +HWTEST_F(UIViewTest, UIViewAlignToSibling_001, TestSize.Level0) +{ + if (view_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + UIViewGroup* viewGroup = new UIViewGroup(); + viewGroup->SetPosition(0, 0, DEFAULE_WIDTH, DEFAULE_HEIGHT); + view_->SetPosition(POS_X, POS_Y, BUTTON_WIDTH, BUTTON_HEIGHT); + viewGroup->Add(view_); + int16_t centerX = (DEFAULE_WIDTH- BUTTON_WIDTH) / 2; // 2: center of x; + int16_t centerY = (DEFAULE_HEIGHT- BUTTON_HEIGHT) / 2; // 2: center of y; + UIView* view2 = new UIView(); + view2->SetPosition(centerX, centerY, BUTTON_WIDTH, BUTTON_HEIGHT); + view2->SetViewId("refView"); + viewGroup->Add(view2); + EXPECT_EQ(view_->GetX(), POS_X); + EXPECT_EQ(view_->GetY(), POS_Y); + view_->AlignLeftToSibling("refView"); + EXPECT_EQ(view_->GetX(), centerX); + EXPECT_EQ(view_->GetY(), POS_Y); + view_->AlignRightToSibling("refView"); + EXPECT_EQ(view_->GetX(), centerX); + EXPECT_EQ(view_->GetY(), POS_Y); + view_->AlignTopToSibling("refView"); + EXPECT_EQ(view_->GetX(), centerX); + EXPECT_EQ(view_->GetY(), centerY); + view_->AlignBottomToSibling("refView"); + EXPECT_EQ(view_->GetX(), centerX); + EXPECT_EQ(view_->GetY(), centerY); + view_->AlignHorCenterToSibling("refView"); + EXPECT_EQ(view_->GetX(), centerX); + EXPECT_EQ(view_->GetY(), centerY); + view_->AlignVerCenterToSibling("refView"); + EXPECT_EQ(view_->GetX(), centerX); + EXPECT_EQ(view_->GetY(), centerY); + + delete view2; + delete viewGroup; +} + +/** + * @tc.name: UIViewLayoutToSibling_001 + * @tc.desc: Verify LayoutToSibling function, equal. + * @tc.type: FUNC + * @tc.require: AR000EEMQF + */ +HWTEST_F(UIViewTest, UIViewLayoutToSibling_001, TestSize.Level0) +{ + if (view_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + UIViewGroup* viewGroup = new UIViewGroup(); + viewGroup->SetPosition(0, 0, DEFAULE_WIDTH, DEFAULE_HEIGHT); + view_->SetPosition(POS_X, POS_Y, BUTTON_WIDTH, BUTTON_HEIGHT); + viewGroup->Add(view_); + int16_t centerX = (DEFAULE_WIDTH- BUTTON_WIDTH) / 2; // 2: center of x; + int16_t centerY = (DEFAULE_HEIGHT- BUTTON_HEIGHT) / 2; // 2: center of y; + UIView* view2 = new UIView(); + view2->SetPosition(centerX, centerY, BUTTON_WIDTH, BUTTON_HEIGHT); + view2->SetViewId("refView"); + viewGroup->Add(view2); + EXPECT_EQ(view_->GetX(), POS_X); + EXPECT_EQ(view_->GetY(), POS_Y); + view_->LayoutLeftToSibling("refView"); + EXPECT_EQ(view_->GetX(), BUTTON_WIDTH); + EXPECT_EQ(view_->GetY(), POS_Y); + view_->LayoutRightToSibling("refView"); + EXPECT_EQ(view_->GetX(), centerX + BUTTON_WIDTH); + EXPECT_EQ(view_->GetY(), POS_Y); + view_->LayoutTopToSibling("refView"); + EXPECT_EQ(view_->GetX(), centerX + BUTTON_WIDTH); + EXPECT_EQ(view_->GetY(), BUTTON_HEIGHT); + view_->LayoutBottomToSibling("refView"); + EXPECT_EQ(view_->GetX(), centerX + BUTTON_WIDTH); + EXPECT_EQ(view_->GetY(), centerY + BUTTON_HEIGHT); + + delete view2; + delete viewGroup; +} + +/** + * @tc.name: Graphic_UIView_Test_Rotate_001 + * @tc.desc: Verify Rotate function, equal. + * @tc.type: FUNC + * @tc.require: SR000F3PEC + */ +HWTEST_F(UIViewTest, Graphic_UIView_Test_Rotate_001, TestSize.Level0) +{ + if (view_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + view_->SetPosition(0, 0, DEFAULE_WIDTH, DEFAULE_HEIGHT); + view_->Rotate(DEFAULE_ANGLE, {0, 0}); + TransformMap& trans = view_->GetTransformMap(); + EXPECT_EQ(view_->GetOrigRect(), trans.GetTransMapRect()); +} + +/** + * @tc.name: Graphic_UIView_Test_Rotate_002 + * @tc.desc: Verify Rotate function, equal. + * @tc.type: FUNC + * @tc.require: AR000F4E5E + */ +HWTEST_F(UIViewTest, Graphic_UIView_Test_Rotate_002, TestSize.Level0) +{ + if (view_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + view_->SetPosition(0, 0, DEFAULE_WIDTH, DEFAULE_HEIGHT); + view_->Rotate(DEFAULE_ANGLE, {0, 0}); + Polygon polygon = view_->GetTransformMap().GetPolygon(); + + EXPECT_EQ(POLYGON1, polygon[0]); // 0: polygon num + EXPECT_EQ(POLYGON2, polygon[1]); // 1: polygon num + EXPECT_EQ(POLYGON3, polygon[2]); // 2: polygon num + EXPECT_EQ(POLYGON4, polygon[3]); // 3: polygon num +} + +/** + * @tc.name: Graphic_UIView_Test_Scale_001 + * @tc.desc: Verify Scale function, equal. + * @tc.type: FUNC + * @tc.require: SR000ERCQH + */ +HWTEST_F(UIViewTest, Graphic_UIView_Test_Scale_001, TestSize.Level0) +{ + if (view_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + view_->SetPosition(0, 0, DEFAULE_WIDTH, DEFAULE_HEIGHT); + view_->Scale(SCALE_VALUE, VIEW_CENTER); + TransformMap& trans = view_->GetTransformMap(); + EXPECT_EQ(view_->GetOrigRect(), trans.GetTransMapRect()); +} + +/** + * @tc.name: Graphic_UIView_Test_Scale_002 + * @tc.desc: Verify Scale function, equal. + * @tc.type: FUNC + * @tc.require: AR000EVI2T + */ +HWTEST_F(UIViewTest, Graphic_UIView_Test_Scale_002, TestSize.Level0) +{ + if (view_ == nullptr) { + EXPECT_NE(0, 0); + return; + } + view_->SetPosition(0, 0, DEFAULE_WIDTH, DEFAULE_HEIGHT); + view_->Scale(SCALE_VALUE, {0, 0}); + Polygon polygon = view_->GetTransformMap().GetPolygon(); + EXPECT_EQ(0, polygon[0].x_); + EXPECT_EQ(0, polygon[0].y_); + EXPECT_EQ((DEFAULE_WIDTH - 1) >> 1, polygon[2].x_); // 2: polygon num + EXPECT_EQ((DEFAULE_WIDTH - 1) >> 1, polygon[2].x_); // 2: polygon num +} +} // namespace OHOS diff --git a/test/unittest/dfx/event_injector_unit_test.cpp b/test/unittest/dfx/event_injector_unit_test.cpp new file mode 100755 index 0000000..0d76103 --- /dev/null +++ b/test/unittest/dfx/event_injector_unit_test.cpp @@ -0,0 +1,443 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "dfx/event_injector.h" + +#if ENABLE_DEBUG +#include "common/graphic_startup.h" +#include "common/screen.h" +#include "components/root_view.h" +#include "common/task_manager.h" +#include "common/input_device_manager.h" +#include "core/render_manager.h" +#include "dock/screen_device_proxy.h" +#include "components/ui_label_button.h" +#include "components/ui_scroll_view.h" +#include +#include "file.h" +#include "font/ui_font.h" +#include +#include "graphic_config.h" +#include "graphic_log.h" +#include "imgdecode/cache_manager.h" +#include "layout/grid_layout.h" +#include +#include +#include "window/window.h" + +using namespace testing::ext; + +enum TestEventInjectorFlag { + FLAG0, + FLAG1 +}; + +namespace { +uint8_t REGISTER_POINT_FLAG = FLAG0; +uint8_t REGISTER_KEY_FLAG = FLAG0; +uint8_t UNREGISTER_POINT_FLAG = FLAG0; +uint8_t UNREGISTER_KEY_FLAG = FLAG0; +uint8_t CLICK_FLAG = FLAG0; +uint8_t LONG_PRESS_FLAG = FLAG0; +uint8_t DRAG_FLAG = FLAG0; +uint8_t KEY_FLAG = FLAG0; +uint8_t MAX_LOOP = 200; +} + +namespace OHOS { +class TestEventInjectorView : public UIView, public RootView::OnKeyActListener { +public: + bool OnLongPressEvent(const LongPressEvent& event) override + { + LONG_PRESS_FLAG = FLAG1; + return true; + } + + bool OnClickEvent(const ClickEvent& event) override + { + CLICK_FLAG = FLAG1; + return true; + } + + bool OnDragEvent(const DragEvent& event) override + { + DRAG_FLAG = FLAG1; + return true; + } + + bool OnKeyAct(UIView& view, const KeyEvent& event) override + { + KEY_FLAG = FLAG1; + return true; + } +}; + +class EventInjectorTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + static void TestApp(); + static void SetUpTestview(TestEventInjectorView* testView, bool touchable, bool draggable); + static void* MainTask(void* args); + static void DeleteChildren(UIView* view); + + static pthread_t mainTaskThread_; + static bool isRepeat_; + static RootView* rootView_; + static GridLayout* layout_; + static TestEventInjectorView* clickView_; + static TestEventInjectorView* dragView_; + static TestEventInjectorView* longPressView_; + static TestEventInjectorView* keyView_; + static Window* window_; +}; + +pthread_t EventInjectorTest::mainTaskThread_ = -1; +bool EventInjectorTest::isRepeat_ = true; +RootView* EventInjectorTest::rootView_ = nullptr; +GridLayout* EventInjectorTest::layout_ = nullptr; +TestEventInjectorView* EventInjectorTest::clickView_ = nullptr; +TestEventInjectorView* EventInjectorTest::dragView_ = nullptr; +TestEventInjectorView* EventInjectorTest::longPressView_ = nullptr; +TestEventInjectorView* EventInjectorTest::keyView_ = nullptr; +Window* EventInjectorTest::window_ = nullptr; + +static void InitHal() +{ + ScreenDevice* display = new ScreenDevice(); + ScreenDeviceProxy::GetInstance()->SetDevice(display); + ScreenDeviceProxy::GetInstance()->SetScreenSize(HORIZONTAL_RESOLUTION, VERTICAL_RESOLUTION); +} + +void EventInjectorTest::SetUpTestCase(void) +{ + GraphicStartUp::Init(); + InitHal(); + TestApp(); + if (pthread_create(&mainTaskThread_, nullptr, MainTask, nullptr) != 0) { + return; + } +} + +void* EventInjectorTest::MainTask(void* args) +{ + while (isRepeat_) { + /* Periodically call TaskHandler(). It could be done in a timer interrupt or an OS task too. */ + OHOS::TaskManager::GetInstance()->TaskHandler(); + usleep(1000 * 10); /* 1000 * 10:10ms Just to let the system breathe */ + } + return nullptr; +} + +void EventInjectorTest::TestApp() +{ + WindowConfig config = {}; + config.rect.SetRect(0, 0, Screen::GetInstance().GetWidth() - 1, Screen::GetInstance().GetHeight() - 1); + window_ = Window::CreateWindow(config); + if (window_ == nullptr) { + GRAPHIC_LOGE("Create window false!"); + return; + } + window_->BindRootView(RootView::GetInstance()); + + if (EventInjector::GetInstance()->RegisterEventInjector(EventDataType::POINT_TYPE)) { + REGISTER_POINT_FLAG = FLAG1; + } + if (EventInjector::GetInstance()->RegisterEventInjector(EventDataType::KEY_TYPE)) { + REGISTER_KEY_FLAG = FLAG1; + } + EventInjector::GetInstance()->SetWindowId(window_->GetWindowId()); + rootView_ = RootView::GetInstance(); + rootView_->SetPosition(0, 0, Screen::GetInstance().GetWidth(), Screen::GetInstance().GetHeight()); + layout_ = new GridLayout(); + layout_->SetPosition(0, 0, Screen::GetInstance().GetWidth(), Screen::GetInstance().GetHeight()); + rootView_->Add(layout_); + layout_->SetLayoutDirection(LAYOUT_VER); + layout_->SetRows(4); /* 4:rows */ + layout_->SetCols(1); + clickView_ = new TestEventInjectorView(); + SetUpTestview(clickView_, true, false); + + longPressView_ = new TestEventInjectorView(); + SetUpTestview(longPressView_, true, false); + + dragView_ = new TestEventInjectorView(); + SetUpTestview(dragView_, true, true); + + keyView_ = new TestEventInjectorView(); + RootView::GetInstance()->SetOnKeyActListener(keyView_); + SetUpTestview(keyView_, true, false); + + layout_->LayoutChildren(); + rootView_->Invalidate(); +} + +void EventInjectorTest::SetUpTestview(TestEventInjectorView* testView, bool touchable, bool draggable) +{ + layout_->Add(testView); + testView->Resize(HORIZONTAL_RESOLUTION, VERTICAL_RESOLUTION / 5); /* 5:ratio */ + testView->SetTouchable(touchable); + testView->SetDraggable(draggable); +} + +void EventInjectorTest::DeleteChildren(UIView* view) +{ + if (view == nullptr) { + return; + } + while (view != nullptr) { + UIView* tempView = view; + view = view->GetNextSibling(); + if (tempView->IsViewGroup()) { + DeleteChildren(static_cast(tempView)->GetChildrenHead()); + } + if (tempView->GetParent()) { + static_cast(tempView->GetParent())->Remove(tempView); + } + delete tempView; + } +} + +void EventInjectorTest::TearDownTestCase(void) +{ + isRepeat_ = false; + pthread_join(mainTaskThread_, nullptr); + Window::DestoryWindow(window_); + DeleteChildren(layout_); + layout_ = nullptr; + + EventInjector::GetInstance()->UnregisterEventInjector(EventDataType::POINT_TYPE); + EventInjector::GetInstance()->UnregisterEventInjector(EventDataType::KEY_TYPE); +} + +/** + * @tc.name: Graphic_EventInjectorTest_Test_RegisterEventInjector_001 + * @tc.desc: Verify RegisterEventInjector function, equal. + * @tc.type: FUNC + * @tc.require: SR000F74SS + */ +HWTEST_F(EventInjectorTest, Graphic_EventInjectorTest_Test_RegisterEventInjector_001, TestSize.Level0) +{ + EXPECT_EQ(REGISTER_POINT_FLAG, FLAG1); + EXPECT_EQ(REGISTER_KEY_FLAG, FLAG1); +} + +/** + * @tc.name: Graphic_EventInjectorTest_Test_SetClickEvent_001 + * @tc.desc: Verify SetClickEvent function, equal. + * @tc.type: FUNC + * @tc.require: AR000F74ST + */ +HWTEST_F(EventInjectorTest, Graphic_EventInjectorTest_Test_SetClickEvent_001, TestSize.Level2) +{ + if (clickView_ == nullptr) { + ADD_FAILURE(); + return; + } + CLICK_FLAG = FLAG0; + /* 2:ratio, 2:ratio */ + Point clickPoint = {static_cast(clickView_->GetRect().GetX() + clickView_->GetWidth() / 2), + static_cast(clickView_->GetRect().GetY() + clickView_->GetHeight() / 2)}; + bool ret = EventInjector::GetInstance()->SetClickEvent(clickPoint); + EXPECT_EQ(ret, true); + uint8_t loop = 0; + while ((loop < MAX_LOOP) && !CLICK_FLAG) { + loop++; + usleep(10000); /* 10000:10ms */ + } + EXPECT_EQ(CLICK_FLAG, FLAG1); +} + +/** + * @tc.name: Graphic_EventInjectorTest_Test_SetDragEvent_001 + * @tc.desc: Verify SetDragEvent function, equal. + * @tc.type: FUNC + * @tc.require: AR000F74ST + */ +HWTEST_F(EventInjectorTest, Graphic_EventInjectorTest_Test_SetDragEvent_001, TestSize.Level2) +{ + if (dragView_ == nullptr) { + ADD_FAILURE(); + return; + } + DRAG_FLAG = FLAG0; + /* 4:ratio, 2:ratio */ + Point startPoint = {static_cast(dragView_->GetRect().GetX() + dragView_->GetWidth() / 4), + static_cast(dragView_->GetRect().GetY() + dragView_->GetHeight() / 2)}; + /* 2:ratio, 2:ratio */ + Point endPoint = {static_cast(dragView_->GetRect().GetX() + dragView_->GetWidth() / 2), + static_cast(dragView_->GetRect().GetY() + dragView_->GetHeight() / 2)}; + bool ret = EventInjector::GetInstance()->SetDragEvent(startPoint, endPoint, 100); /* 100:drag time (ms) */ + EXPECT_EQ(ret, true); + uint8_t loop = 0; + while ((loop < MAX_LOOP) && !DRAG_FLAG) { + loop++; + usleep(10000); /* 10000:10ms */ + } + EXPECT_EQ(DRAG_FLAG, FLAG1); +} + +/** + * @tc.name: Graphic_EventInjectorTest_Test_SetDragEvent_002 + * @tc.desc: Verify SetDragEvent function, abnormal branch, SetDragEvent failure(dragTime is too short), equal. + * @tc.type: FUNC + * @tc.require: AR000F74ST + */ +HWTEST_F(EventInjectorTest, Graphic_EventInjectorTest_Test_SetDragEvent_002, TestSize.Level0) +{ + if (dragView_ == nullptr) { + ADD_FAILURE(); + return; + } + /* 4:ratio, 2:ratio */ + Point startPoint = {static_cast(dragView_->GetRect().GetX() + dragView_->GetWidth() / 4), + static_cast(dragView_->GetRect().GetY() + dragView_->GetHeight() / 2)}; + /* 2:ratio, 2:ratio */ + Point endPoint = {static_cast(dragView_->GetRect().GetX() + dragView_->GetWidth() / 2), + static_cast(dragView_->GetRect().GetY() + dragView_->GetHeight() / 2)}; + bool ret = EventInjector::GetInstance()->SetDragEvent(startPoint, endPoint, INDEV_READ_PERIOD); + EXPECT_EQ(ret, false); +} + +/** + * @tc.name: Graphic_EventInjectorTest_Test_SetDragEvent_003 + * @tc.desc: Verify SetDragEvent function, abnormal branch, SetDragEvent failure(dragTime is too long), equal. + * @tc.type: FUNC + * @tc.require: AR000F74ST + */ +HWTEST_F(EventInjectorTest, Graphic_EventInjectorTest_Test_SetDragEvent_003, TestSize.Level0) +{ + if (dragView_ == nullptr) { + ADD_FAILURE(); + return; + } + /* 4:ratio, 2:ratio */ + Point startPoint = {static_cast(dragView_->GetRect().GetX() + dragView_->GetWidth() / 4), + static_cast(dragView_->GetRect().GetY() + dragView_->GetHeight() / 2)}; + /* 2:ratio, 2:ratio */ + Point endPoint = {static_cast(dragView_->GetRect().GetX() + dragView_->GetWidth() / 2), + static_cast(dragView_->GetRect().GetY() + dragView_->GetHeight() / 2)}; + bool ret = EventInjector::GetInstance()->SetDragEvent(startPoint, endPoint, 6000); /* 6000:drag time (ms) */ + EXPECT_EQ(ret, false); +} + +/** + * @tc.name: Graphic_EventInjectorTest_Test_SetLongPressEvent_001 + * @tc.desc: Verify SetLongPressEvent function, equal. + * @tc.type: FUNC + * @tc.require: AR000F74ST + */ +HWTEST_F(EventInjectorTest, Graphic_EventInjectorTest_Test_SetLongPressEvent_001, TestSize.Level2) +{ + if (longPressView_ == nullptr) { + ADD_FAILURE(); + return; + } + sleep(2); /* 2:2s */ + LONG_PRESS_FLAG = FLAG0; + /* 2:ratio, 2:ratio */ + Point longPressPoint = {static_cast(longPressView_->GetRect().GetX() + longPressView_->GetWidth() / 2), + static_cast(longPressView_->GetRect().GetY() + longPressView_->GetHeight() / 2)}; + bool ret = EventInjector::GetInstance()->SetLongPressEvent(longPressPoint); + EXPECT_EQ(ret, true); + uint8_t loop = 0; + while ((loop < MAX_LOOP) && !LONG_PRESS_FLAG) { + loop++; + usleep(10000); /* 10000:10ms */ + } + EXPECT_EQ(LONG_PRESS_FLAG, FLAG1); +} + +/** + * @tc.name: Graphic_EventInjectorTest_Test_SetLongPressEvent_002 + * @tc.desc: Verify SetLongPressEvent function, abnormal branch, SetLongPressEvent failure, equal. + * @tc.type: FUNC + * @tc.require: AR000F74ST + */ +HWTEST_F(EventInjectorTest, Graphic_EventInjectorTest_Test_SetLongPressEvent_002, TestSize.Level0) +{ + if (longPressView_ == nullptr) { + ADD_FAILURE(); + return; + } + /* 2:ratio, 2:ratio */ + Point longPressPoint = {static_cast(longPressView_->GetRect().GetX() + longPressView_->GetWidth() / 2), + static_cast(longPressView_->GetRect().GetY() + longPressView_->GetHeight() / 2)}; + /* 20:loop */ + for (uint8_t i = 0; i < 20; i++) { + EventInjector::GetInstance()->SetLongPressEvent(longPressPoint); + } + bool ret = EventInjector::GetInstance()->SetLongPressEvent(longPressPoint); + EXPECT_EQ(ret, false); +} + +/** + * @tc.name: Graphic_EventInjectorTest_Test_SetKeyEvent_001 + * @tc.desc: Verify SetKeyEvent function, equal. + * @tc.type: FUNC + * @tc.require: AR000F74ST + */ +HWTEST_F(EventInjectorTest, Graphic_EventInjectorTest_Test_SetKeyEvent_001, TestSize.Level2) +{ + /* 26:keyId */ + uint16_t keyId = 26; + EventInjector::GetInstance()->SetKeyEvent(keyId, InputDevice::STATE_PRESS); + uint8_t loop = 0; + while ((loop < MAX_LOOP) && !KEY_FLAG) { + loop++; + usleep(10000); /* 10000:10ms */ + } + EXPECT_EQ(KEY_FLAG, FLAG1); +} + +/** + * @tc.name: Graphic_EventInjectorTest_Test_SetKeyEvent_002 + * @tc.desc: Verify SetKeyEvent function, abnormal branch, SetKeyEvent failure, equal. + * @tc.type: FUNC + * @tc.require: AR000F74ST + */ +HWTEST_F(EventInjectorTest, Graphic_EventInjectorTest_Test_SetKeyEvent_002, TestSize.Level0) +{ + /* 26:keyId */ + uint16_t keyId = 26; + /* 200:loop */ + for (uint8_t i = 0; i < 200; i++) { + EventInjector::GetInstance()->SetKeyEvent(keyId, InputDevice::STATE_PRESS); + } + bool ret = EventInjector::GetInstance()->SetKeyEvent(keyId, InputDevice::STATE_PRESS); + EXPECT_EQ(ret, false); +} + +/** + * @tc.name: Graphic_EventInjectorTest_Test_UnregisterEventInjector_001 + * @tc.desc: Verify UnregisterEventInjector function, equal. + * @tc.type: FUNC + * @tc.require: AR000F74ST + */ +HWTEST_F(EventInjectorTest, Graphic_EventInjectorTest_Test_UnregisterEventInjector_001, TestSize.Level0) +{ + EventInjector::GetInstance()->UnregisterEventInjector(EventDataType::POINT_TYPE); + if (!EventInjector::GetInstance()->IsEventInjectorRegistered(EventDataType::POINT_TYPE)) { + UNREGISTER_POINT_FLAG = FLAG1; + } + EventInjector::GetInstance()->UnregisterEventInjector(EventDataType::KEY_TYPE); + if (!EventInjector::GetInstance()->IsEventInjectorRegistered(EventDataType::KEY_TYPE)) { + UNREGISTER_KEY_FLAG = FLAG1; + } + EXPECT_EQ(UNREGISTER_POINT_FLAG, FLAG1); + EXPECT_EQ(UNREGISTER_KEY_FLAG, FLAG1); +} +} +#endif // ENABLE_DEBUG \ No newline at end of file diff --git a/test/unittest/events/cancel_event_unit_test.cpp b/test/unittest/events/cancel_event_unit_test.cpp new file mode 100755 index 0000000..f0d33fa --- /dev/null +++ b/test/unittest/events/cancel_event_unit_test.cpp @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "events/cancel_event.h" + +#include +#include + +using namespace testing::ext; +namespace OHOS { +namespace { + const Point INIT_POS = { 100, 200 }; +} +class CancelEventTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + static CancelEvent* cancelEvent_; +}; + +CancelEvent* CancelEventTest::cancelEvent_ = nullptr; + +void CancelEventTest::SetUpTestCase(void) +{ + if (cancelEvent_ == nullptr) { + cancelEvent_ = new CancelEvent(INIT_POS); + } +} + +void CancelEventTest::TearDownTestCase(void) +{ + if (cancelEvent_ != nullptr) { + delete cancelEvent_; + cancelEvent_ = nullptr; + } +} + +/** + * @tc.name: CancelEventConstructor_001 + * @tc.desc: Verify Constructor function, equal. + * @tc.type: FUNC + * @tc.require: SR000DRSH4 + */ +HWTEST_F(CancelEventTest, CancelEventConstructor_001, TestSize.Level0) +{ + if (cancelEvent_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + EXPECT_EQ(cancelEvent_->GetCurrentPos().x, INIT_POS.x); + EXPECT_EQ(cancelEvent_->GetCurrentPos().y, INIT_POS.y); +} +} // namespace OHOS diff --git a/test/unittest/events/click_event_unit_test.cpp b/test/unittest/events/click_event_unit_test.cpp new file mode 100755 index 0000000..b338b63 --- /dev/null +++ b/test/unittest/events/click_event_unit_test.cpp @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "events/click_event.h" + +#include +#include + +using namespace testing::ext; +namespace OHOS { +namespace { + const Point INIT_POS = { 100, 200 }; +} +class ClickEventTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + static ClickEvent* clickEvent_; +}; + +ClickEvent* ClickEventTest::clickEvent_ = nullptr; + +void ClickEventTest::SetUpTestCase(void) +{ + if (clickEvent_ == nullptr) { + clickEvent_ = new ClickEvent(INIT_POS); + } +} + +void ClickEventTest::TearDownTestCase(void) +{ + if (clickEvent_ != nullptr) { + delete clickEvent_; + clickEvent_ = nullptr; + } +} +/** + * @tc.name: ClickEventConstructor_001 + * @tc.desc: Verify Constructor function, equal. + * @tc.type: FUNC + * @tc.require: SR000DRSH4 + */ +HWTEST_F(ClickEventTest, ClickEventConstructor_001, TestSize.Level0) +{ + if (clickEvent_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + EXPECT_EQ(clickEvent_->GetCurrentPos().x, INIT_POS.x); + EXPECT_EQ(clickEvent_->GetCurrentPos().y, INIT_POS.y); +} +} // namespace OHOS diff --git a/test/unittest/events/drag_event_unit_test.cpp b/test/unittest/events/drag_event_unit_test.cpp new file mode 100755 index 0000000..a85e811 --- /dev/null +++ b/test/unittest/events/drag_event_unit_test.cpp @@ -0,0 +1,180 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "events/drag_event.h" + +#include +#include + +using namespace testing::ext; +namespace OHOS { +namespace { + const Point NEW_POS = { 100, 200 }; + const Point LAST_POS = { 150, 250 }; + const Point TOTAL_LEN = { 50, 150 }; + constexpr uint8_t DIRECTION_LEFT_TO_RIGHT = 0; + constexpr uint8_t DIRECTION_RIGHT_TO_LEFT = 1; + constexpr uint8_t DIRECTION_TOP_TO_BOTTOM = 2; + constexpr uint8_t DIRECTION_BOTTOM_TO_TOP = 3; +} + +class DragEventTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + static DragEvent* dragEvent_; +}; + +DragEvent* DragEventTest::dragEvent_ = nullptr; + +void DragEventTest::SetUpTestCase(void) +{ + if (dragEvent_ == nullptr) { + dragEvent_ = new DragEvent(NEW_POS, LAST_POS, TOTAL_LEN); + } +} + +void DragEventTest::TearDownTestCase(void) +{ + if (dragEvent_ != nullptr) { + delete dragEvent_; + dragEvent_ = nullptr; + } +} +/** + * @tc.name: DragEventConstructor_001 + * @tc.desc: Verify Constructor function, equal. + * @tc.type: FUNC + * @tc.require: SR000DRSH4 + */ +HWTEST_F(DragEventTest, DragEventConstructor_001, TestSize.Level0) +{ + if (dragEvent_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + EXPECT_EQ(dragEvent_->GetCurrentPos().x, NEW_POS.x); + EXPECT_EQ(dragEvent_->GetCurrentPos().y, NEW_POS.y); +} + +/** + * @tc.name: DragEventGetLastPoint_001 + * @tc.desc: Verify GetLastPoint function, equal. + * @tc.type: FUNC + * @tc.require: SR000DRSH4 + */ +HWTEST_F(DragEventTest, DragEventGetLastPoint_001, TestSize.Level0) +{ + if (dragEvent_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + EXPECT_EQ(dragEvent_->GetLastPoint().x, LAST_POS.x); + EXPECT_EQ(dragEvent_->GetLastPoint().y, LAST_POS.y); +} + +/** + * @tc.name: DragEventGetStartPoint_001 + * @tc.desc: Verify GetStartPoint function, equal. + * @tc.type: FUNC + * @tc.require: SR000DRSH4 + */ +HWTEST_F(DragEventTest, DragEventGetStartPoint_001, TestSize.Level0) +{ + if (dragEvent_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + EXPECT_EQ(dragEvent_->GetStartPoint().x, NEW_POS.x - TOTAL_LEN.x); + EXPECT_EQ(dragEvent_->GetStartPoint().y, NEW_POS.y - TOTAL_LEN.y); +} + +/** + * @tc.name: DragEventSetPreLastPoint_001 + * @tc.desc: Verify SetPreLastPoint function, equal. + * @tc.type: FUNC + * @tc.require: SR000DRSH4 + */ +HWTEST_F(DragEventTest, DragEventSetPreLastPoint_001, TestSize.Level0) +{ + if (dragEvent_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + const Point preLastPos = { 20, 40 }; + dragEvent_->SetPreLastPoint(preLastPos); + EXPECT_EQ(dragEvent_->GetPreLastPoint().x, preLastPos.x); + EXPECT_EQ(dragEvent_->GetPreLastPoint().y, preLastPos.y); +} + +/** + * @tc.name: DragEventGetDragDirection_001 + * @tc.desc: Verify GetDragDirection function, equal. + * @tc.type: FUNC + * @tc.require: SR000DRSH4 + */ +HWTEST_F(DragEventTest, DragEventGetDragDirection_001, TestSize.Level0) +{ + if (dragEvent_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + Point startPos = dragEvent_->GetStartPoint(); + Point currentPos = dragEvent_->GetCurrentPos(); + if (MATH_ABS(currentPos.x - startPos.x) >= MATH_ABS(currentPos.y - startPos.y)) { + if (currentPos.x > startPos.x) { + EXPECT_EQ(dragEvent_->GetDragDirection(), DIRECTION_LEFT_TO_RIGHT); + } else { + EXPECT_EQ(dragEvent_->GetDragDirection(), DIRECTION_RIGHT_TO_LEFT); + } + } else { + if (currentPos.y > startPos.y) { + EXPECT_EQ(dragEvent_->GetDragDirection(), DIRECTION_TOP_TO_BOTTOM); + } else { + EXPECT_EQ(dragEvent_->GetDragDirection(), DIRECTION_BOTTOM_TO_TOP); + } + } +} + +/** + * @tc.name: DragEventGetDeltaX_001 + * @tc.desc: Verify GetDeltaX function, equal. + * @tc.type: FUNC + * @tc.require: SR000DRSH4 + */ +HWTEST_F(DragEventTest, DragEventGetDeltaX_001, TestSize.Level0) +{ + if (dragEvent_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + EXPECT_EQ(dragEvent_->GetDeltaX(), NEW_POS.x - LAST_POS.x); +} + +/** + * @tc.name: DragEventGetDeltaY_001 + * @tc.desc: Verify GetDeltaY function, equal. + * @tc.type: FUNC + * @tc.require: SR000DRSH4 + */ +HWTEST_F(DragEventTest, DragEventGetDeltaY_001, TestSize.Level0) +{ + if (dragEvent_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + EXPECT_EQ(dragEvent_->GetDeltaY(), NEW_POS.y - LAST_POS.y); +} +} // namespace OHOS diff --git a/test/unittest/events/event_bubble_unit_test.cpp b/test/unittest/events/event_bubble_unit_test.cpp new file mode 100755 index 0000000..5c95a8d --- /dev/null +++ b/test/unittest/events/event_bubble_unit_test.cpp @@ -0,0 +1,438 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#if ENABLE_DEBUG +#include "common/graphic_startup.h" +#include "common/screen.h" +#include "components/root_view.h" +#include "common/task_manager.h" +#include "common/input_device_manager.h" +#include "core/render_manager.h" +#include "dock/screen_device_proxy.h" +#include "components/ui_label_button.h" +#include "components/ui_scroll_view.h" +#include +#include "file.h" +#include "font/ui_font.h" +#include +#include "graphic_config.h" +#include "graphic_log.h" +#include "imgdecode/cache_manager.h" +#include "layout/grid_layout.h" +#include + +using namespace testing::ext; + +enum TestEventFlag { + FLAG0, + FLAG1 +}; + +namespace { +uint8_t REGISTER_POINT_FLAG = FLAG0; +uint8_t REGISTER_KEY_FLAG = FLAG0; +uint8_t CLICK_FLAG = FLAG0; +uint8_t LONG_PRESS_FLAG = FLAG0; +uint8_t PRESS_FLAG = FLAG0; +uint8_t DRAG_FLAG = FLAG0; +uint8_t KEY_FLAG = FLAG0; +} + +namespace OHOS { +class TestEventBubbleView : public UIView, public RootView::OnKeyActListener { +public: + bool OnLongPressEvent(const LongPressEvent& event) override + { + longPressEventFlag_ = FLAG1; + return true; + } + + bool OnClickEvent(const ClickEvent& event) override + { + clickEventFlag_ = FLAG1; + return true; + } + + bool OnDragEvent(const DragEvent& event) override + { + dragEventFlag_ = FLAG1; + return true; + } + + bool OnKeyAct(UIView& view, const KeyEvent& event) override + { + KEY_FLAG = FLAG1; + return true; + } + +private: + bool longPressEventFlag_; + bool clickEventFlag_; + bool dragEventFlag_; +}; + +class EventBubbleTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + static void TestApp(); + static void SetUpTestview(TestEventBubbleView *testView, bool touchable, bool draggable); + static void DeleteChildren(UIView* view); + + static RootView* rootView_; + static GridLayout* layout_; + static TestEventBubbleView* clickView_; + static TestEventBubbleView* dragView_; + static TestEventBubbleView* longPressView_; + static TestEventBubbleView* keyView_; + static TestEventBubbleView* unTouchView_; +}; + +class TestOnClickListener : public UIView::OnClickListener { +public: + explicit TestOnClickListener(bool isConsume) : isConsume_(isConsume) {} + virtual ~TestOnClickListener() {} + virtual bool OnClick(UIView& view, const ClickEvent& event) + { + CLICK_FLAG = FLAG1; + return isConsume_; + } + +private: + bool isConsume_; +}; + +class TestOnLongPressListener : public UIView::OnLongPressListener { +public: + explicit TestOnLongPressListener(bool isConsume) : isConsume_(isConsume) {} + virtual ~TestOnLongPressListener() {} + virtual bool OnLongPress(UIView& view, const LongPressEvent& event) + { + LONG_PRESS_FLAG = FLAG1; + return isConsume_; + } + +private: + bool isConsume_; +}; + + +class TestOnTouchListener : public UIView::OnTouchListener { +public: + explicit TestOnTouchListener(bool isConsume) : isConsume_(isConsume) + { + } + virtual ~TestOnTouchListener() {} + virtual bool OnPress(UIView& view, const PressEvent& event) + { + PRESS_FLAG = FLAG1; + return isConsume_; + } + +private: + bool isConsume_; +}; + +class TestOnDragListener : public UIView::OnDragListener { +public: + explicit TestOnDragListener(bool isConsume) : isConsume_(isConsume) + { + } + virtual ~TestOnDragListener() {} + virtual bool OnDrag(DragEvent& event) + { + DRAG_FLAG = FLAG1; + return isConsume_; + } + +private: + bool isConsume_; +}; + +RootView* EventBubbleTest::rootView_ = nullptr; +GridLayout* EventBubbleTest::layout_ = nullptr; +TestEventBubbleView* EventBubbleTest::clickView_ = nullptr; +TestEventBubbleView* EventBubbleTest::dragView_ = nullptr; +TestEventBubbleView* EventBubbleTest::longPressView_ = nullptr; +TestEventBubbleView* EventBubbleTest::keyView_ = nullptr; +TestEventBubbleView* EventBubbleTest::unTouchView_ = nullptr; + +static void InitHal() +{ + ScreenDevice* display = new ScreenDevice(); + ScreenDeviceProxy::GetInstance()->SetDevice(display); + ScreenDeviceProxy::GetInstance()->SetScreenSize(HORIZONTAL_RESOLUTION, VERTICAL_RESOLUTION); +} + +void EventBubbleTest::SetUpTestCase(void) +{ + GraphicStartUp::Init(); + InitHal(); + TestApp(); +} + +void EventBubbleTest::TestApp() +{ + rootView_ = RootView::GetInstance(); + rootView_->SetTouchable(true); + rootView_->SetPosition(0, 0, Screen::GetInstance().GetWidth(), Screen::GetInstance().GetHeight()); + layout_ = new GridLayout(); + layout_->SetPosition(0, 0, Screen::GetInstance().GetWidth(), Screen::GetInstance().GetHeight()); + rootView_->Add(layout_); + layout_->SetLayoutDirection(LAYOUT_VER); + layout_->SetRows(6); /* 6:rows */ + layout_->SetCols(1); + + clickView_ = new TestEventBubbleView(); + SetUpTestview(clickView_, true, false); + + longPressView_ = new TestEventBubbleView(); + SetUpTestview(longPressView_, true, false); + + dragView_ = new TestEventBubbleView(); + SetUpTestview(dragView_, true, true); + + unTouchView_ = new TestEventBubbleView(); + SetUpTestview(unTouchView_, false, false); + + keyView_ = new TestEventBubbleView(); + RootView::GetInstance()->SetOnKeyActListener(keyView_); + SetUpTestview(keyView_, true, false); + + layout_->LayoutChildren(); + rootView_->Invalidate(); +} + +void EventBubbleTest::SetUpTestview(TestEventBubbleView *testView, bool touchable, bool draggable) +{ + layout_->Add(testView); + testView->Resize(HORIZONTAL_RESOLUTION, VERTICAL_RESOLUTION / 7); /* 7:ratio */ + testView->SetTouchable(touchable); + testView->SetDraggable(draggable); +} + +void EventBubbleTest::DeleteChildren(UIView* view) +{ + if (view == nullptr) { + return; + } + while (view != nullptr) { + UIView* tempView = view; + view = view->GetNextSibling(); + if (tempView->IsViewGroup()) { + DeleteChildren(static_cast(tempView)->GetChildrenHead()); + } + if (tempView->GetParent()) { + static_cast(tempView->GetParent())->Remove(tempView); + } + delete tempView; + } +} + +void EventBubbleTest::TearDownTestCase(void) +{ + DeleteChildren(layout_); + layout_ = nullptr; +} + +/** + * @tc.name: Graphic_EventBubbleTest_Test_GetExtraMsg_SetExtraMsg_007 + * @tc.desc: Verify GetExtraMsg, SetExtraMsg function, equal. + * @tc.type: FUNC + * @tc.require: AR000F4E5C + */ +HWTEST_F(EventBubbleTest, Graphic_EventBubbleTest_Test_GetExtraMsg_SetExtraMsg_007, TestSize.Level0) +{ + /* test for GetExtraMsg */ + TestEventBubbleView* view = new TestEventBubbleView(); + EXPECT_EQ(view->GetExtraMsg(), nullptr); + + /* test for SetExtraMsg */ + UIView::ViewExtraMsg *extraMsg = new UIView::ViewExtraMsg(); + extraMsg->elementPtr = malloc(sizeof(char)); + view->SetExtraMsg(extraMsg); + EXPECT_EQ(view->GetExtraMsg()->elementPtr, extraMsg->elementPtr); + free(extraMsg->elementPtr); + delete extraMsg; + delete view; +} + +/** + * @tc.name: Graphic_EventBubbleTest_Test_UIView_GetTargetView_008 + * @tc.desc: Verify UIView::GetTargetView equal. + * @tc.type: FUNC + * @tc.require: AR000F4E5C + */ +HWTEST_F(EventBubbleTest, Graphic_EventBubbleTest_Test_UIViewGroup_GetTargetView_008, TestSize.Level0) +{ + if ((clickView_ == nullptr) || (rootView_ == nullptr)) { + return; + } + /* test for touchable view */ + /* 2:ratio, 2:ratio */ + Point clickPoint = {(int16_t)(clickView_->GetRect().GetX() + clickView_->GetWidth() / 2), + (int16_t)(clickView_->GetRect().GetY() + clickView_->GetHeight() / 2)}; + UIView* curView = nullptr; + UIView* targetView = nullptr; + rootView_->GetTargetView(clickPoint, &curView, &targetView); + EXPECT_EQ(curView, clickView_); + EXPECT_EQ(targetView, clickView_); + + /* test for unTouchable view */ + if (unTouchView_ == nullptr) { + return; + } + /* 2:ratio, 2:ratio */ + Point clickPoint2 = {(int16_t)(unTouchView_->GetRect().GetX() + unTouchView_->GetWidth() / 2), + (int16_t)(unTouchView_->GetRect().GetY() + unTouchView_->GetHeight() / 2)}; + curView = nullptr; + targetView = nullptr; + rootView_->GetTargetView(clickPoint2, &curView, &targetView); + + EXPECT_EQ(curView, rootView_); + EXPECT_EQ(targetView, unTouchView_); +} + +/** + * @tc.name: Graphic_EventBubbleTest_Test_UIView_GetTargetView_009 + * @tc.desc: Verify UIView::GetTargetView equal. + * @tc.type: FUNC + * @tc.require: AR000F4E5C + */ +HWTEST_F(EventBubbleTest, Graphic_EventBubbleTest_Test_UIView_GetTargetView_009, TestSize.Level0) +{ + if ((clickView_ == nullptr) || (rootView_ == nullptr)) { + return; + } + /* test for touchable view */ + /* 2:ratio, 2:ratio */ + Point clickPoint = {(int16_t)(clickView_->GetRect().GetX() + clickView_->GetWidth() / 2), + (int16_t)(clickView_->GetRect().GetY() + clickView_->GetHeight() / 2)}; + UIView* curView = nullptr; + UIView* targetView = nullptr; + clickView_->GetTargetView(clickPoint, &curView, &targetView); + EXPECT_EQ(curView, clickView_); + EXPECT_EQ(targetView, clickView_); + + /* test for unTouchable view */ + if (unTouchView_ == nullptr) { + return; + } + /* 2:ratio, 2:ratio */ + Point clickPoint2 = {(int16_t)(unTouchView_->GetRect().GetX() + unTouchView_->GetWidth() / 2), + (int16_t)(unTouchView_->GetRect().GetY() + unTouchView_->GetHeight() / 2)}; + curView = nullptr; + targetView = nullptr; + unTouchView_->GetTargetView(clickPoint2, &curView, &targetView); + + EXPECT_EQ(curView, nullptr); + EXPECT_EQ(targetView, unTouchView_); +} + +/** + * @tc.name: Graphic_EventBubbleTest_Test_UIView_OnClick_010 + * @tc.desc: Verify UIView::OnClick equal. + * @tc.type: FUNC + * @tc.require: SR000F3PEA + */ +HWTEST_F(EventBubbleTest, Graphic_EventBubbleTest_Test_UIView_OnClick_010, TestSize.Level0) +{ + /* 2:ratio, 2:ratio */ + Point clickPoint = {(int16_t)(clickView_->GetRect().GetX() + clickView_->GetWidth() / 2), + (int16_t)(clickView_->GetRect().GetY() + clickView_->GetHeight() / 2)}; + ClickEvent clickEvent(clickPoint); + + /* test for not comsumed view */ + TestOnClickListener* clickListener = new TestOnClickListener(false); + bool ret = clickListener->OnClick(*clickView_, clickEvent); + EXPECT_EQ(ret, false); + EXPECT_EQ(CLICK_FLAG, true); + delete clickListener; + + /* test for comsumed view */ + CLICK_FLAG = false; + TestOnClickListener* clickListener2 = new TestOnClickListener(true); + ret = clickListener->OnClick(*clickView_, clickEvent); + EXPECT_EQ(ret, true); + EXPECT_EQ(CLICK_FLAG, true); + delete clickListener2; +} + +/** + * @tc.name: Graphic_EventBubbleTest_Test_UIView_OnLongPress_011 + * @tc.desc: Verify UIView::OnLongPress equal. + * @tc.type: FUNC + * @tc.require: AR000F4E5C + */ +HWTEST_F(EventBubbleTest, Graphic_EventBubbleTest_Test_UIView_OnLongPress_011, TestSize.Level0) +{ + /* 2:ratio, 2:ratio */ + Point longPressPoint = {(int16_t)(longPressView_->GetRect().GetX() + longPressView_->GetWidth() / 2), + (int16_t)(longPressView_->GetRect().GetY() + longPressView_->GetHeight() / 2)}; + uint32_t pressTimeStamp = 2; /* 2:second */ + LongPressEvent longPressEvent(longPressPoint, pressTimeStamp); + + /* test for not comsumed view */ + TestOnLongPressListener* longPressListener = new TestOnLongPressListener(false); + bool ret = longPressListener->OnLongPress(*clickView_, longPressEvent); + EXPECT_EQ(ret, false); + EXPECT_EQ(LONG_PRESS_FLAG, true); + delete longPressListener; + + /* test for comsumed view */ + LONG_PRESS_FLAG = false; + TestOnLongPressListener* longPressListener2 = new TestOnLongPressListener(true); + ret = longPressListener2->OnLongPress(*clickView_, longPressEvent); + EXPECT_EQ(ret, true); + EXPECT_EQ(LONG_PRESS_FLAG, true); + delete longPressListener2; +} + +/** + * @tc.name: Graphic_EventBubbleTest_Test_UIView_OnDrag_012 + * @tc.desc: Verify UIView::OnDrag equal. + * @tc.type: FUNC + * @tc.require: AR000F4E5C + */ +HWTEST_F(EventBubbleTest, Graphic_EventBubbleTest_Test_UIView_OnDrag_012, TestSize.Level0) +{ + /* 2:ratio, 2:ratio */ + Point dragCurPoint = {(int16_t)(dragView_->GetRect().GetX() + dragView_->GetWidth() / 2), + (int16_t)(dragView_->GetRect().GetY() + dragView_->GetHeight() / 2)}; + /* 3:ratio, 3:ratio */ + Point dragLastPoint = {(int16_t)(dragView_->GetRect().GetX() + dragView_->GetWidth() / 3), + (int16_t)(dragView_->GetRect().GetY() + dragView_->GetHeight() / 3)}; + Point dragLen; + dragLen.x = dragCurPoint.x - dragLastPoint.x; + dragLen.y = dragCurPoint.y - dragLastPoint.y; + DragEvent dragEvent(dragCurPoint, dragLastPoint, dragLen); + + /* test for not comsumed view */ + TestOnDragListener* dragListener = new TestOnDragListener(false); + bool ret = dragListener->OnDrag(dragEvent); + EXPECT_EQ(ret, false); + EXPECT_EQ(DRAG_FLAG, true); + delete dragListener; + + /* test for comsumed view */ + LONG_PRESS_FLAG = false; + TestOnDragListener* dragListener2 = new TestOnDragListener(true); + ret = dragListener2->OnDrag(dragEvent); + EXPECT_EQ(ret, true); + EXPECT_EQ(DRAG_FLAG, true); + delete dragListener2; +} +} // namespace OHOS +#endif // ENABLE_DEBUG diff --git a/test/unittest/events/event_unit_test.cpp b/test/unittest/events/event_unit_test.cpp new file mode 100755 index 0000000..4955f41 --- /dev/null +++ b/test/unittest/events/event_unit_test.cpp @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "events/event.h" + +#include +#include + +using namespace testing::ext; +namespace OHOS { +namespace { + const Point INIT_POS = { 100, 200 }; + const TimeType TIME_STAMP = 10; +} + +class EventTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + static Event* event_; +}; + +Event* EventTest::event_ = nullptr; + +void EventTest::SetUpTestCase(void) +{ + if (event_ == nullptr) { + event_ = new Event(INIT_POS); + } +} + +void EventTest::TearDownTestCase(void) +{ + if (event_ != nullptr) { + delete event_; + event_ = nullptr; + } +} +/** + * @tc.name: EventConstructor_001 + * @tc.desc: Verify Constructor function, equal. + * @tc.type: FUNC + * @tc.require: SR000DRSH4 + */ +HWTEST_F(EventTest, EventConstructor_001, TestSize.Level0) +{ + if (event_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + EXPECT_EQ(event_->GetCurrentPos().x, INIT_POS.x); + EXPECT_EQ(event_->GetCurrentPos().y, INIT_POS.y); +} + +/** + * @tc.name: EventSetTimeStamp_001 + * @tc.desc: Verify SetTimeStamp function, equal. + * @tc.type: FUNC + * @tc.require: SR000DRSH4 + */ +HWTEST_F(EventTest, EventSetTimeStamp_001, TestSize.Level0) +{ + if (event_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + event_->SetTimeStamp(TIME_STAMP); + EXPECT_EQ(event_->GetTimeStamp(), TIME_STAMP); +} +} // namespace OHOS \ No newline at end of file diff --git a/test/unittest/events/key_event_unit_test.cpp b/test/unittest/events/key_event_unit_test.cpp new file mode 100755 index 0000000..781ab39 --- /dev/null +++ b/test/unittest/events/key_event_unit_test.cpp @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "events/key_event.h" + +#include +#include + +using namespace testing::ext; +namespace OHOS { +namespace { + const uint16_t KEY_ID = 10; + const uint16_t STATE = 20; +} + +class KeyEventTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + static KeyEvent* keyEvent_; +}; + +KeyEvent* KeyEventTest::keyEvent_ = nullptr; + +void KeyEventTest::SetUpTestCase(void) +{ + if (keyEvent_ == nullptr) { + keyEvent_ = new KeyEvent(KEY_ID, STATE); + } +} + +void KeyEventTest::TearDownTestCase(void) +{ + if (keyEvent_ != nullptr) { + delete keyEvent_; + keyEvent_ = nullptr; + } +} + +/** + * @tc.name: KeyEventGetKeyId_001 + * @tc.desc: Verify GetKeyId function, equal. + * @tc.type: FUNC + * @tc.require: SR000DRSH4 + */ +HWTEST_F(KeyEventTest, KeyEventGetKeyId_001, TestSize.Level0) +{ + if (keyEvent_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + EXPECT_EQ(keyEvent_->GetKeyId(), KEY_ID); +} + +/** + * @tc.name: KeyEventGetState_001 + * @tc.desc: Verify GetState function, equal. + * @tc.type: FUNC + * @tc.require: SR000DRSH4 + */ +HWTEST_F(KeyEventTest, KeyEventGetState_001, TestSize.Level0) +{ + if (keyEvent_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + EXPECT_EQ(keyEvent_->GetState(), STATE); +} +} // namespace OHOS \ No newline at end of file diff --git a/test/unittest/events/long_press_event_unit_test.cpp b/test/unittest/events/long_press_event_unit_test.cpp new file mode 100755 index 0000000..d90a5d4 --- /dev/null +++ b/test/unittest/events/long_press_event_unit_test.cpp @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "events/long_press_event.h" + +#include +#include + +using namespace testing::ext; +namespace OHOS { +namespace { + const Point INIT_POS = {100, 200}; + const TimeType TIME_STAMP = 10; +} + +class LongPressEventTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + static LongPressEvent* longPressEvent_; +}; + +LongPressEvent* LongPressEventTest::longPressEvent_ = nullptr; + +void LongPressEventTest::SetUpTestCase(void) +{ + if (longPressEvent_ == nullptr) { + longPressEvent_ = new LongPressEvent(INIT_POS, TIME_STAMP); + } +} + +void LongPressEventTest::TearDownTestCase(void) +{ + if (longPressEvent_ != nullptr) { + delete longPressEvent_; + longPressEvent_ = nullptr; + } +} +/** + * @tc.name: LongPressEventConstructor_001 + * @tc.desc: Verify GetCurrentPos function, equal. + * @tc.type: FUNC + * @tc.require: SR000DRSH4 + */ +HWTEST_F(LongPressEventTest, LongPressEventConstructor_001, TestSize.Level0) +{ + if (longPressEvent_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + EXPECT_EQ(longPressEvent_->GetCurrentPos().x, INIT_POS.x); + EXPECT_EQ(longPressEvent_->GetCurrentPos().y, INIT_POS.y); +} + +/** + * @tc.name: LongPressEventConstructor_002 + * @tc.desc: Verify GetCurrentPos function, equal. + * @tc.type: FUNC + * @tc.require: SR000DRSH4 + */ +HWTEST_F(LongPressEventTest, LongPressEventConstructor_002, TestSize.Level0) +{ + if (longPressEvent_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + EXPECT_EQ(longPressEvent_->GetTimeStamp(), TIME_STAMP); +} +} // namespace OHOS diff --git a/test/unittest/events/press_event_unit_test.cpp b/test/unittest/events/press_event_unit_test.cpp new file mode 100755 index 0000000..036ec47 --- /dev/null +++ b/test/unittest/events/press_event_unit_test.cpp @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "events/press_event.h" + +#include +#include + +using namespace testing::ext; +namespace OHOS { +namespace { + const Point INIT_POS = { 100, 200 }; +} +class PressEventTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + static PressEvent* pressEvent_; +}; + +PressEvent* PressEventTest::pressEvent_ = nullptr; + +void PressEventTest::SetUpTestCase(void) +{ + if (pressEvent_ == nullptr) { + pressEvent_ = new PressEvent(INIT_POS); + } +} + +void PressEventTest::TearDownTestCase(void) +{ + if (pressEvent_ != nullptr) { + delete pressEvent_; + pressEvent_ = nullptr; + } +} + +/** + * @tc.name: PressEventConstructor_001 + * @tc.desc: Verify Constructor function, equal. + * @tc.type: FUNC + * @tc.require: SR000DRSH4 + */ +HWTEST_F(PressEventTest, PressEventConstructor_001, TestSize.Level0) +{ + if (pressEvent_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + EXPECT_EQ(pressEvent_->GetCurrentPos().x, INIT_POS.x); + EXPECT_EQ(pressEvent_->GetCurrentPos().y, INIT_POS.y); +} +} // namespace OHOS \ No newline at end of file diff --git a/test/unittest/events/release_event_unit_test.cpp b/test/unittest/events/release_event_unit_test.cpp new file mode 100755 index 0000000..2b4875e --- /dev/null +++ b/test/unittest/events/release_event_unit_test.cpp @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "events/release_event.h" + +#include +#include + +using namespace testing::ext; +namespace OHOS { +namespace { + const Point INIT_POS = { 100, 200 }; +} +class ReleaseEventTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + static ReleaseEvent* releaseEvent_; +}; + +ReleaseEvent* ReleaseEventTest::releaseEvent_ = nullptr; + +void ReleaseEventTest::SetUpTestCase(void) +{ + if (releaseEvent_ == nullptr) { + releaseEvent_ = new ReleaseEvent(INIT_POS); + } +} + +void ReleaseEventTest::TearDownTestCase(void) +{ + if (releaseEvent_ != nullptr) { + delete releaseEvent_; + releaseEvent_ = nullptr; + } +} + +/** + * @tc.name: ReleaseEventConstructor_001 + * @tc.desc: Verify GetCurrentPos function, equal. + * @tc.type: FUNC + * @tc.require: SR000DRSH4 + */ +HWTEST_F(ReleaseEventTest, ReleaseEventConstructor_001, TestSize.Level0) +{ + EXPECT_EQ(releaseEvent_->GetCurrentPos().x, INIT_POS.x); + EXPECT_EQ(releaseEvent_->GetCurrentPos().y, INIT_POS.y); +} +} // namespace OHOS \ No newline at end of file diff --git a/test/unittest/events/virtual_device_event_unit_test.cpp b/test/unittest/events/virtual_device_event_unit_test.cpp new file mode 100755 index 0000000..f1560af --- /dev/null +++ b/test/unittest/events/virtual_device_event_unit_test.cpp @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "events/virtual_device_event.h" + +#include +#include + +using namespace testing::ext; +namespace OHOS { +namespace { + const uint16_t TYPE = 10; + const uint16_t VALUE = 20; +} + +class VirtualDeviceEventTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + static VirtualDeviceEvent* virtualDeviceEvent_; +}; + +VirtualDeviceEvent* VirtualDeviceEventTest::virtualDeviceEvent_ = nullptr; + +void VirtualDeviceEventTest::SetUpTestCase(void) +{ + if (virtualDeviceEvent_ == nullptr) { + virtualDeviceEvent_ = new VirtualDeviceEvent(TYPE, VALUE); + } +} + +void VirtualDeviceEventTest::TearDownTestCase(void) +{ + if (virtualDeviceEvent_ != nullptr) { + delete virtualDeviceEvent_; + virtualDeviceEvent_ = nullptr; + } +} +/** + * @tc.name: VirtualDeviceEventConstructor_001 + * @tc.desc: Verify Constructor function, equal. + * @tc.type: FUNC + * @tc.require: SR000DRSH4 + */ +HWTEST_F(VirtualDeviceEventTest, VirtualDeviceEventConstructor_001, TestSize.Level0) +{ + if (virtualDeviceEvent_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + EXPECT_EQ(virtualDeviceEvent_->GetType(), TYPE); +} + +/** + * @tc.name: VirtualDeviceEventConstructor_002 + * @tc.desc: Verify Constructor function, equal. + * @tc.type: FUNC + * @tc.require: SR000DRSH4 + */ +HWTEST_F(VirtualDeviceEventTest, VirtualDeviceEventConstructor_002, TestSize.Level0) +{ + if (virtualDeviceEvent_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + EXPECT_EQ(virtualDeviceEvent_->GetState(), VALUE); +} +} // namespace OHOS \ No newline at end of file diff --git a/test/unittest/font/ui_font_unit_test.cpp b/test/unittest/font/ui_font_unit_test.cpp new file mode 100755 index 0000000..01c4459 --- /dev/null +++ b/test/unittest/font/ui_font_unit_test.cpp @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "font/ui_font.h" +#include "font/ui_font_vector.h" + +#include +#include + +using namespace testing::ext; +namespace OHOS { +namespace { + constexpr uint8_t FONT_ERROR_RET = 0xFF; +} +class UIFontTest : public testing::Test { +public: + UIFontTest() {} + virtual ~UIFontTest() {} + + static void SetUpTestCase() {}; + static void TearDownTestCase() {}; +}; + +/** + * @tc.name: Graphic_Font_Test_GetInstance_001 + * @tc.desc: Verify UIFont::GetInstance function, not nullptr. + * @tc.type: FUNC + * @tc.require: SR000F3PEK + */ +HWTEST_F(UIFontTest, Graphic_Font_Test_GetInstance_001, TestSize.Level0) +{ + UIFont* font = UIFont::GetInstance(); + EXPECT_NE(font, nullptr); +} + +/** + * @tc.name: Graphic_Font_Test_GetInstance_002 + * @tc.desc: Verify UIFont::GetInstance function, equal. + * @tc.type: FUNC + * @tc.require: SR000F3PEK + */ +HWTEST_F(UIFontTest, Graphic_Font_Test_GetInstance_002, TestSize.Level0) +{ + UIFont* font = UIFont::GetInstance(); + bool ret = UIFont::GetInstance()->IsVectorFont(); + EXPECT_EQ(ret, true); +} + +/** + * @tc.name: Graphic_Font_Test_RegisterFontInfo_001 + * @tc.desc: Verify UIFont::RegisterFontInfo function, error font name. + * @tc.type: FUNC + * @tc.require: AR000F3R7C + */ +HWTEST_F(UIFontTest, Graphic_Font_Test_RegisterFontInfo_001, TestSize.Level0) +{ + uint8_t ret = UIFont::GetInstance()->RegisterFontInfo("error"); + EXPECT_EQ(ret, FONT_ERROR_RET); +} + +/** + * @tc.name: Graphic_Font_Test_RegisterFontInfo_002 + * @tc.desc: Verify UIFont::RegisterFontInfo function, error font file path. + * @tc.type: FUNC + * @tc.require: AR000F3R7C + */ +HWTEST_F(UIFontTest, Graphic_Font_Test_RegisterFontInfo_002, TestSize.Level0) +{ + uint8_t ret = UIFont::GetInstance()->RegisterFontInfo("ui-font.ttf"); + EXPECT_EQ(ret, FONT_ERROR_RET); +} + +/** + * @tc.name: Graphic_Font_Test_UnregisterFontInfo_001 + * @tc.desc: Verify UIFont::UnregisterFontInfo function, error font name. + * @tc.type: FUNC + * @tc.require: AR000F3R7C + */ +HWTEST_F(UIFontTest, Graphic_Font_Test_UnregisterFontInfo_001, TestSize.Level0) +{ + uint8_t ret = UIFont::GetInstance()->UnregisterFontInfo("error font name"); + EXPECT_EQ(ret, FONT_ERROR_RET); +} + +/** + * @tc.name: Graphic_Font_Test_UnregisterFontInfo_002 + * @tc.desc: Verify UIFont::UnregisterFontInfo function, unregister fontsTable. + * @tc.type: FUNC + * @tc.require: AR000F3R7C + */ +HWTEST_F(UIFontTest, Graphic_Font_Test_UnregisterFontInfo_002, TestSize.Level0) +{ + const UITextLanguageFontParam* fontsTable = nullptr; + uint8_t ret = UIFont::GetInstance()->UnregisterFontInfo(fontsTable, 0); + EXPECT_EQ(ret, 0); +} +} // namespace OHOS \ No newline at end of file diff --git a/test/unittest/image/image_load_unit_test.cpp b/test/unittest/image/image_load_unit_test.cpp new file mode 100755 index 0000000..166d557 --- /dev/null +++ b/test/unittest/image/image_load_unit_test.cpp @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "imgdecode/image_load.h" + +#include "file.h" +#include "mem_api.h" +#include "test_resource_config.h" + +#include +#include + +using namespace testing::ext; + +namespace { +constexpr uint8_t MAX_FILE_NUM = 2; +} + +namespace OHOS { +class ImageTest : public testing::Test { +public: + static void SetUpTestCase(); + static void TearDownTestCase(); + + static void ResetFds(); + static void InitImageInfo(ImageInfo& info); + + static int32_t imgResFds_[MAX_FILE_NUM]; + static ImageInfo imgInfos_[MAX_FILE_NUM]; + static uint32_t sizes_[MAX_FILE_NUM]; +}; + +int32_t ImageTest::imgResFds_[MAX_FILE_NUM]; +ImageInfo ImageTest::imgInfos_[MAX_FILE_NUM]; +uint32_t ImageTest::sizes_[MAX_FILE_NUM]; + +void ImageTest::SetUpTestCase() +{ + const char* paths[] = { + IMAGE_DIR "A001_001.bin", + IMAGE_DIR "A001_002.bin" + }; + for (int i = 0; i < MAX_FILE_NUM; i++) { + imgResFds_[i] = open(paths[i], O_RDONLY); + struct stat fileStat; + fstat(imgResFds_[i], &fileStat); + sizes_[i] = fileStat.st_size - sizeof(ImageHeader); + read(imgResFds_[i], &imgInfos_[i].header, sizeof(ImageHeader)); + } +} + +void ImageTest::TearDownTestCase() +{ + for (int i = 0; i < MAX_FILE_NUM; i++) { + close(imgResFds_[i]); + } +} + +void ImageTest::ResetFds() +{ + for (int i = 0; i < MAX_FILE_NUM; i++) { + lseek(imgResFds_[i], sizeof(ImageHeader), SEEK_SET); + } +} + +/** + * @tc.name: Graphic_Image_Test_GetImageInfo_001 + * @tc.desc: Verify ImageLoad::GetImageInfo function, invalid param. + * @tc.type: FUNC + * @tc.require: AR000F74ST + */ +HWTEST_F(ImageTest, Graphic_Image_Test_GetImageInfo_001, TestSize.Level0) +{ + /* test invalid fd */ + bool ret = ImageLoad::GetImageInfo(-1, sizes_[0], imgInfos_[0]); + EXPECT_EQ(ret, false); + + /* test invalid size */ + ret = ImageLoad::GetImageInfo(imgResFds_[0], 0, imgInfos_[0]); + EXPECT_EQ(ret, false); +} + +/** + * @tc.name: Graphic_Image_Test_GetImageInfo_002 + * @tc.desc: Verify ImageLoad::GetImageInfo function, invalid compress mode. + * @tc.type: FUNC + * @tc.require: SR000ERCR7 + */ +HWTEST_F(ImageTest, Graphic_Image_Test_GetImageInfo_002, TestSize.Level0) +{ + ResetFds(); + + auto info = imgInfos_[0]; + info.header.compressMode = COMPRESS_MODE_BLOCK_ALG; + bool ret = ImageLoad::GetImageInfo(imgResFds_[0], sizes_[0], info); + EXPECT_EQ(ret, false); +} + +/** + * @tc.name: Graphic_Image_Test_GetImageInfo_003 + * @tc.desc: Verify ImageLoad::GetImageInfo function, multi-images. + * @tc.type: FUNC + * @tc.require: AR000F74ST + */ +HWTEST_F(ImageTest, Graphic_Image_Test_GetImageInfo_003, TestSize.Level0) +{ + ResetFds(); + + for (int32_t i = 0; i < MAX_FILE_NUM; i++) { + bool success = ImageLoad::GetImageInfo(imgResFds_[i], sizes_[i], imgInfos_[i]); + if (success) { + ImageCacheFree(imgInfos_[i]); + } else { + EXPECT_EQ(success, true); + } + } +} +} // namespace OHOS \ No newline at end of file diff --git a/test/unittest/layout/list_layout_unit_test.cpp b/test/unittest/layout/list_layout_unit_test.cpp new file mode 100755 index 0000000..e873c36 --- /dev/null +++ b/test/unittest/layout/list_layout_unit_test.cpp @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "layout/list_layout.h" + +#include +#include + +using namespace testing::ext; +namespace OHOS { +class ListLayoutTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + static ListLayout* listLayout_; +}; + +ListLayout* ListLayoutTest::listLayout_ = nullptr; + +void ListLayoutTest::SetUpTestCase(void) +{ + if (listLayout_ == nullptr) { + listLayout_ = new ListLayout(); + } +} + +void ListLayoutTest::TearDownTestCase(void) +{ + if (listLayout_ != nullptr) { + delete listLayout_; + listLayout_ = nullptr; + } +} +/** + * @tc.name: ListLayoutSetDirection_001 + * @tc.desc: Verify SetDirection function, equal. + * @tc.type: FUNC + * @tc.require: AR000DSMR7 + */ +HWTEST_F(ListLayoutTest, ListLayoutSetDirection_001, TestSize.Level0) +{ + if (listLayout_ == nullptr) { + EXPECT_EQ(1, 0); + return; + } + EXPECT_EQ(listLayout_->GetDirection(), 1); + + listLayout_->SetDirection(0); + EXPECT_EQ(listLayout_->GetDirection(), 0); +} +} // namespace OHOS \ No newline at end of file diff --git a/test/unittest/render/render_uni_test.cpp b/test/unittest/render/render_uni_test.cpp new file mode 100644 index 0000000..45bae1f --- /dev/null +++ b/test/unittest/render/render_uni_test.cpp @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include +#include + +#include "common/graphic_startup.h" +#include "common/task_manager.h" +#include "components/root_view.h" +#include "components/ui_view.h" +#include "components/ui_view_group.h" +#include "window/window.h" + +using namespace testing::ext; +namespace OHOS { +static uint16_t g_measureCount = 0; +class RenderTest : public testing::Test { +public: + RenderTest() {} + virtual ~RenderTest() {} + + static void SetUpTestCase() + { + GraphicStartUp::Init(); + } + static void TearDownTestCase() {} + + static void CreateDefaultWindow(RootView* rootView, int x, int y) + { + WindowConfig config = {}; + config.rect = rootView->GetRect(); + config.rect.SetPosition(x, y); + Window* window = Window::CreateWindow(config); + if (window != nullptr) { + window->BindRootView(rootView); + } + } + + static void DestoryWindow(RootView* rootView) + { + Window::DestoryWindow(rootView->GetBoundWindow()); + } +}; + +class UITestView : public UIView { +public: + UITestView() {} + virtual ~UITestView() {} + + void ReMeasure() override + { + g_measureCount++; + } +}; + +class UITestViewGroup : public UIViewGroup { +public: + UITestViewGroup() {} + virtual ~UITestViewGroup() {} + + void ReMeasure() override + { + g_measureCount++; + } +}; + +/** + * @tc.name: Graphic_RenderTest_Test_Measuer_001 + * @tc.desc: Verity measure call when render + * @tc.type: FUNC + * @tc.require: SR000FH555 + */ +HWTEST_F(RenderTest, Graphic_RenderTest_Test_Measuer_001, TestSize.Level0) +{ + RootView* rootView = RootView::GetWindowRootView(); + rootView->SetWidth(600); // 600: width + rootView->SetHeight(500); // 500: height + rootView->SetPosition(0, 0); + UITestView* view1 = new UITestView(); + UITestViewGroup* vg1 = new UITestViewGroup(); + rootView->Add(vg1); + vg1->Add(view1); + vg1->Invalidate(); + rootView->Add(vg1); + rootView->Invalidate(); + g_measureCount = 0; + + RenderTest::CreateDefaultWindow(rootView, 0, 0); + TaskManager::GetInstance()->TaskHandler(); + EXPECT_EQ(g_measureCount, 2); // 2: measure view + rootView->RemoveAll(); + delete view1; + delete vg1; + RenderTest::DestoryWindow(rootView); + RootView::DestoryWindowRootView(rootView); +} + +/** + * @tc.name: Graphic_RenderTest_Test_Measuer_02 + * @tc.desc: Verity measure call when view invisible + * @tc.type: FUNC + * @tc.require: AR000FH556 + */ +HWTEST_F(RenderTest, Graphic_RenderTest_Test_Measuer_02, TestSize.Level0) +{ + RootView* rootView = RootView::GetWindowRootView(); + rootView->SetWidth(600); // 600: width + rootView->SetHeight(500); // 500: height + rootView->SetPosition(0, 0); + UITestView* view1 = new UITestView(); + UITestViewGroup* vg1 = new UITestViewGroup(); + rootView->Add(vg1); + vg1->Add(view1); + // invisible view not need to measure + view1->SetVisible(false); + rootView->Invalidate(); + g_measureCount = 0; + + RenderTest::CreateDefaultWindow(rootView, 0, 0); + TaskManager::GetInstance()->TaskHandler(); + EXPECT_EQ(g_measureCount, 1); + + rootView->RemoveAll(); + delete view1; + delete vg1; + RenderTest::DestoryWindow(rootView); + RootView::DestoryWindowRootView(rootView); +} +} // namespace OHOS diff --git a/test/unittest/rotate/ui_rotate_input_unit_test.cpp b/test/unittest/rotate/ui_rotate_input_unit_test.cpp new file mode 100644 index 0000000..11f894e --- /dev/null +++ b/test/unittest/rotate/ui_rotate_input_unit_test.cpp @@ -0,0 +1,173 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ +#include "components/ui_abstract_progress.h" +#include "components/ui_list.h" +#include "components/ui_picker.h" +#include "components/ui_scroll_view.h" +#include "components/ui_slider.h" +#include "components/ui_swipe_view.h" +#include "components/ui_time_picker.h" +#include "dock/focus_manager.h" +#include +#include + +using namespace testing::ext; +namespace OHOS { +class UIRotateInputTest : public testing::Test { +public: + UIRotateInputTest() {} + virtual ~UIRotateInputTest() {} + + static void SetUpTestCase(){}; + static void TearDownTestCase(){}; +}; + +/** + * @tc.name: Graphic_RotateInput_Test_SetRotateFactor_001 + * @tc.desc: Verify UIRotateInput::SetRotateFactor function. + * @tc.type: FUNC + * @tc.require: SR000ERCQF + */ +HWTEST_F(UIRotateInputTest, Graphic_RotateInput_Test_SetRotateFactor_001, TestSize.Level0) +{ + UIScrollView* scroll = new UIScrollView(); + scroll->SetRotateFactor(10); // 10 : rotate factor + EXPECT_EQ(scroll->GetRotateFactor(), 10); + delete scroll; +} + +/** + * @tc.name: Graphic_RotateInput_Test_SetRotateFactor_002 + * @tc.desc: Verify UIRotateInput::SetRotateFactor function. + * @tc.type: FUNC + * @tc.require: SR000ERCQF + */ +HWTEST_F(UIRotateInputTest, Graphic_RotateInput_Test_SetRotateFactor_002, TestSize.Level0) +{ + UISwipeView* swipe = new UISwipeView(); + swipe->SetRotateFactor(10); // 10 : rotate factor + EXPECT_EQ(swipe->GetRotateFactor(), 10); + delete swipe; +} + +/** + * @tc.name: Graphic_RotateInput_Test_SetRotateFactor_003 + * @tc.desc: Verify UIRotateInput::SetRotateFactor function. + * @tc.type: FUNC + * @tc.require: SR000ERCQF + */ +HWTEST_F(UIRotateInputTest, Graphic_RotateInput_Test_SetRotateFactor_003, TestSize.Level0) +{ + UIList* list = new UIList(); + list->SetRotateFactor(10); // 10 : rotate factor + EXPECT_EQ(list->GetRotateFactor(), 10); + delete list; +} + +/** + * @tc.name: Graphic_RotateInput_Test_SetRotateFactor_004 + * @tc.desc: Verify UIRotateInput::SetRotateFactor function. + * @tc.type: FUNC + * @tc.require: SR000ERCQF + */ +HWTEST_F(UIRotateInputTest, Graphic_RotateInput_Test_SetRotateFactor_004, TestSize.Level0) +{ + UIList* list = new UIList(); + list->SetRotateFactor(20); // 10 : rotate factor + EXPECT_NE(list->GetRotateFactor(), 10); + delete list; +} + +/** + * @tc.name: Graphic_RotateInput_Test_SetRotateFactor_005 + * @tc.desc: Verify UIRotateInput::SetRotateFactor function. + * @tc.type: FUNC + * @tc.require: AR000EVI2R + */ +HWTEST_F(UIRotateInputTest, Graphic_RotateInput_Test_SetRotateFactor_005, TestSize.Level0) +{ + UISlider* slider = new UISlider(); + slider->SetRotateFactor(10); // 10 : rotate factor + EXPECT_EQ(slider->GetRotateFactor(), 10); + delete slider; +} + +/** + * @tc.name: Graphic_RotateInput_Test_RequestFocus_001 + * @tc.desc: Verify UIRotateInput::RequestFocus function. + * @tc.type: FUNC + * @tc.require: SR000FH553 + */ +HWTEST_F(UIRotateInputTest, Graphic_RotateInput_Test_RequestFocus_001, TestSize.Level0) +{ + UIScrollView* scroll = new UIScrollView(); + scroll->RequestFocus(); + EXPECT_EQ(scroll, FocusManager::GetInstance()->GetFocusedView()); + delete scroll; +} +/** + * @tc.name: Graphic_RotateInput_Test_RequestFocus_002 + * @tc.desc: Verify UIRotateInput::RequestFocus function. + * @tc.type: FUNC + * @tc.require: AR000FH554 + */ +HWTEST_F(UIRotateInputTest, Graphic_RotateInput_Test_RequestFocus_002, TestSize.Level0) +{ + UITimePicker* timePicker = new UITimePicker(); + timePicker->RequestFocus(); + EXPECT_EQ(timePicker, FocusManager::GetInstance()->GetFocusedView()); + delete timePicker; +} +/** + * @tc.name: Graphic_RotateInput_Test_RequestFocus_003 + * @tc.desc: Verify UIRotateInput::RequestFocus function. + * @tc.type: FUNC + * @tc.require: AR000FH554 + */ +HWTEST_F(UIRotateInputTest, Graphic_RotateInput_Test_RequestFocus_003, TestSize.Level0) +{ + UISwipeView* swipe = new UISwipeView(); + swipe->RequestFocus(); + EXPECT_EQ(swipe, FocusManager::GetInstance()->GetFocusedView()); + delete swipe; +} +/** + * @tc.name: Graphic_RotateInput_Test_RequestFocus_004 + * @tc.desc: Verify UIList::RequestFocus function. + * @tc.type: FUNC + * @tc.require: SR000ERCQG + */ +HWTEST_F(UIRotateInputTest, Graphic_RotateInput_Test_RequestFocus_004, TestSize.Level0) +{ + UIList* list = new UIList(); + list->RequestFocus(); + EXPECT_EQ(list, FocusManager::GetInstance()->GetFocusedView()); + delete list; +} +/** + * @tc.name: Graphic_RotateInput_Test_RequestFocus_005 + * @tc.desc: Verify UIRotateInput::RequestFocus function. + * @tc.type: FUNC + * @tc.require: AR000EVI2S + */ +HWTEST_F(UIRotateInputTest, Graphic_RotateInput_Test_RequestFocus_005, TestSize.Level0) +{ + UISlider* slider = new UISlider(); + slider->RequestFocus(); + EXPECT_EQ(slider, FocusManager::GetInstance()->GetFocusedView()); + delete slider; +} +} + diff --git a/test/unittest/themes/theme_manager_unit_test.cpp b/test/unittest/themes/theme_manager_unit_test.cpp new file mode 100755 index 0000000..660e0b2 --- /dev/null +++ b/test/unittest/themes/theme_manager_unit_test.cpp @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "themes/theme_manager.h" + +#include +#include + +using namespace testing::ext; +namespace OHOS { +class ThemeManagerTest : public testing::Test { +public: + static void SetUpTestCase(void) {} + static void TearDownTestCase(void) {} +}; + +/** + * @tc.name: ThemeManagerSetCurrent_001 + * @tc.desc: Verify SetCurrent function, equal. + * @tc.type: FUNC + * @tc.require: AR000DTCI5 + */ +HWTEST_F(ThemeManagerTest, ThemeManagerSetCurrent_001, TestSize.Level0) +{ + Theme* theme = new Theme(); + if (theme == nullptr) { + EXPECT_EQ(1, 0); + return; + } + ThemeManager::GetInstance().SetCurrent(theme); + EXPECT_EQ(ThemeManager::GetInstance().GetCurrent(), theme); + + delete theme; +} +} // namespace OHOS \ No newline at end of file diff --git a/tools/qt/simulator/config/faces/default/B024_002.bin b/tools/qt/simulator/config/faces/default/B024_002.bin new file mode 100644 index 0000000..ea46636 Binary files /dev/null and b/tools/qt/simulator/config/faces/default/B024_002.bin differ diff --git a/tools/qt/simulator/config/faces/default/B024_009.bin b/tools/qt/simulator/config/faces/default/B024_009.bin new file mode 100644 index 0000000..853ae68 Binary files /dev/null and b/tools/qt/simulator/config/faces/default/B024_009.bin differ diff --git a/tools/qt/simulator/config/faces/default/B024_010.bin b/tools/qt/simulator/config/faces/default/B024_010.bin new file mode 100644 index 0000000..3b298f7 Binary files /dev/null and b/tools/qt/simulator/config/faces/default/B024_010.bin differ diff --git a/tools/qt/simulator/config/faces/default/B024_011.bin b/tools/qt/simulator/config/faces/default/B024_011.bin new file mode 100644 index 0000000..9923a94 Binary files /dev/null and b/tools/qt/simulator/config/faces/default/B024_011.bin differ diff --git a/tools/qt/simulator/config/images/blue.png b/tools/qt/simulator/config/images/blue.png new file mode 100644 index 0000000..aa46de8 Binary files /dev/null and b/tools/qt/simulator/config/images/blue.png differ diff --git a/tools/qt/simulator/config/images/blue_argb8888.bin b/tools/qt/simulator/config/images/blue_argb8888.bin new file mode 100644 index 0000000..e4411dc Binary files /dev/null and b/tools/qt/simulator/config/images/blue_argb8888.bin differ diff --git a/tools/qt/simulator/config/images/blue_compress.bin b/tools/qt/simulator/config/images/blue_compress.bin new file mode 100644 index 0000000..93409c5 Binary files /dev/null and b/tools/qt/simulator/config/images/blue_compress.bin differ diff --git a/tools/qt/simulator/config/images/blue_rgb565.bin b/tools/qt/simulator/config/images/blue_rgb565.bin new file mode 100644 index 0000000..9f95d9f Binary files /dev/null and b/tools/qt/simulator/config/images/blue_rgb565.bin differ diff --git a/tools/qt/simulator/config/images/blue_rgb888.bin b/tools/qt/simulator/config/images/blue_rgb888.bin new file mode 100644 index 0000000..f1e045f Binary files /dev/null and b/tools/qt/simulator/config/images/blue_rgb888.bin differ diff --git a/tools/qt/simulator/config/images/green.png b/tools/qt/simulator/config/images/green.png new file mode 100644 index 0000000..216cf27 Binary files /dev/null and b/tools/qt/simulator/config/images/green.png differ diff --git a/tools/qt/simulator/config/images/ic_arrow_right.png b/tools/qt/simulator/config/images/ic_arrow_right.png new file mode 100644 index 0000000..b7159bb Binary files /dev/null and b/tools/qt/simulator/config/images/ic_arrow_right.png differ diff --git a/tools/qt/simulator/config/images/ic_back.png b/tools/qt/simulator/config/images/ic_back.png new file mode 100644 index 0000000..3620c46 Binary files /dev/null and b/tools/qt/simulator/config/images/ic_back.png differ diff --git a/tools/qt/simulator/config/images/image_animator_0.bin b/tools/qt/simulator/config/images/image_animator_0.bin new file mode 100644 index 0000000..d87bfec Binary files /dev/null and b/tools/qt/simulator/config/images/image_animator_0.bin differ diff --git a/tools/qt/simulator/config/images/image_animator_1.bin b/tools/qt/simulator/config/images/image_animator_1.bin new file mode 100644 index 0000000..f07b10c Binary files /dev/null and b/tools/qt/simulator/config/images/image_animator_1.bin differ diff --git a/tools/qt/simulator/config/images/image_animator_2.bin b/tools/qt/simulator/config/images/image_animator_2.bin new file mode 100644 index 0000000..c0d1f14 Binary files /dev/null and b/tools/qt/simulator/config/images/image_animator_2.bin differ diff --git a/tools/qt/simulator/config/images/image_animator_3.bin b/tools/qt/simulator/config/images/image_animator_3.bin new file mode 100644 index 0000000..572e4ad Binary files /dev/null and b/tools/qt/simulator/config/images/image_animator_3.bin differ diff --git a/tools/qt/simulator/config/images/jpeg.jpg b/tools/qt/simulator/config/images/jpeg.jpg new file mode 100644 index 0000000..a026e48 Binary files /dev/null and b/tools/qt/simulator/config/images/jpeg.jpg differ diff --git a/tools/qt/simulator/config/images/png_16_gray.png b/tools/qt/simulator/config/images/png_16_gray.png new file mode 100644 index 0000000..d13d972 Binary files /dev/null and b/tools/qt/simulator/config/images/png_16_gray.png differ diff --git a/tools/qt/simulator/config/images/png_1_palette.png b/tools/qt/simulator/config/images/png_1_palette.png new file mode 100644 index 0000000..1916a31 Binary files /dev/null and b/tools/qt/simulator/config/images/png_1_palette.png differ diff --git a/tools/qt/simulator/config/images/png_24_rgb.png b/tools/qt/simulator/config/images/png_24_rgb.png new file mode 100644 index 0000000..70cad98 Binary files /dev/null and b/tools/qt/simulator/config/images/png_24_rgb.png differ diff --git a/tools/qt/simulator/config/images/png_2_palette.png b/tools/qt/simulator/config/images/png_2_palette.png new file mode 100644 index 0000000..886c0b3 Binary files /dev/null and b/tools/qt/simulator/config/images/png_2_palette.png differ diff --git a/tools/qt/simulator/config/images/png_32_rgba.png b/tools/qt/simulator/config/images/png_32_rgba.png new file mode 100644 index 0000000..c6ca9cc Binary files /dev/null and b/tools/qt/simulator/config/images/png_32_rgba.png differ diff --git a/tools/qt/simulator/config/images/png_4_palette.png b/tools/qt/simulator/config/images/png_4_palette.png new file mode 100644 index 0000000..37cc111 Binary files /dev/null and b/tools/qt/simulator/config/images/png_4_palette.png differ diff --git a/tools/qt/simulator/config/images/png_8_gray.png b/tools/qt/simulator/config/images/png_8_gray.png new file mode 100644 index 0000000..5e895c0 Binary files /dev/null and b/tools/qt/simulator/config/images/png_8_gray.png differ diff --git a/tools/qt/simulator/config/images/png_8_palette.png b/tools/qt/simulator/config/images/png_8_palette.png new file mode 100644 index 0000000..545f65f Binary files /dev/null and b/tools/qt/simulator/config/images/png_8_palette.png differ diff --git a/tools/qt/simulator/config/images/red.png b/tools/qt/simulator/config/images/red.png new file mode 100644 index 0000000..4cd1dd3 Binary files /dev/null and b/tools/qt/simulator/config/images/red.png differ diff --git a/tools/qt/simulator/config/images/red_compress.bin b/tools/qt/simulator/config/images/red_compress.bin new file mode 100644 index 0000000..439b89d Binary files /dev/null and b/tools/qt/simulator/config/images/red_compress.bin differ diff --git a/tools/qt/simulator/config/images/sliderBackground.bin b/tools/qt/simulator/config/images/sliderBackground.bin new file mode 100644 index 0000000..8dc9e5e Binary files /dev/null and b/tools/qt/simulator/config/images/sliderBackground.bin differ diff --git a/tools/qt/simulator/config/images/sliderIndicator.bin b/tools/qt/simulator/config/images/sliderIndicator.bin new file mode 100644 index 0000000..2012fc0 Binary files /dev/null and b/tools/qt/simulator/config/images/sliderIndicator.bin differ diff --git a/tools/qt/simulator/config/images/sliderKnob.bin b/tools/qt/simulator/config/images/sliderKnob.bin new file mode 100644 index 0000000..8ad5091 Binary files /dev/null and b/tools/qt/simulator/config/images/sliderKnob.bin differ diff --git a/tools/qt/simulator/config/images/yellow.png b/tools/qt/simulator/config/images/yellow.png new file mode 100644 index 0000000..78f7bb2 Binary files /dev/null and b/tools/qt/simulator/config/images/yellow.png differ diff --git a/tools/qt/simulator/default_resource/videoplayer_mute.png b/tools/qt/simulator/default_resource/videoplayer_mute.png new file mode 100644 index 0000000..635d427 Binary files /dev/null and b/tools/qt/simulator/default_resource/videoplayer_mute.png differ diff --git a/tools/qt/simulator/default_resource/videoplayer_pause.png b/tools/qt/simulator/default_resource/videoplayer_pause.png new file mode 100644 index 0000000..76f2aec Binary files /dev/null and b/tools/qt/simulator/default_resource/videoplayer_pause.png differ diff --git a/tools/qt/simulator/default_resource/videoplayer_play.png b/tools/qt/simulator/default_resource/videoplayer_play.png new file mode 100644 index 0000000..f28e73a Binary files /dev/null and b/tools/qt/simulator/default_resource/videoplayer_play.png differ diff --git a/tools/qt/simulator/default_resource/videoplayer_play_center.png b/tools/qt/simulator/default_resource/videoplayer_play_center.png new file mode 100644 index 0000000..92438ad Binary files /dev/null and b/tools/qt/simulator/default_resource/videoplayer_play_center.png differ diff --git a/tools/qt/simulator/default_resource/videoplayer_volume.png b/tools/qt/simulator/default_resource/videoplayer_volume.png new file mode 100644 index 0000000..7224ec6 Binary files /dev/null and b/tools/qt/simulator/default_resource/videoplayer_volume.png differ diff --git a/tools/qt/simulator/drivers/config.h b/tools/qt/simulator/drivers/config.h new file mode 100755 index 0000000..9d86adf --- /dev/null +++ b/tools/qt/simulator/drivers/config.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef GRAPHIC_LITE_CONFIG_H +#define GRAPHIC_LITE_CONFIG_H + +#define USE_MOUSE 1 +#define USE_MOUSEWHEEL 1 + +#endif // GRAPHIC_LITE_CONFIG_H diff --git a/tools/qt/simulator/drivers/display/gui_thread.cpp b/tools/qt/simulator/drivers/display/gui_thread.cpp new file mode 100755 index 0000000..fb64777 --- /dev/null +++ b/tools/qt/simulator/drivers/display/gui_thread.cpp @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "gui_thread.h" + +namespace OHOS { +GUIThread::GUIThread(QObject* parent) : QThread(parent) +{ + monitor_ = Monitor::GetInstance(); +} + +GUIThread::~GUIThread() +{ + monitor_ = nullptr; +} + +void GUIThread::run() +{ + if (monitor_ != nullptr) { + monitor_->GUILoopStart(); + } +} + +void GUIThread::Quit() +{ + if (monitor_ != nullptr) { + monitor_->GUILoopQuit(); + } +} +} // namespace OHOS diff --git a/tools/qt/simulator/drivers/display/gui_thread.h b/tools/qt/simulator/drivers/display/gui_thread.h new file mode 100755 index 0000000..4a5bccc --- /dev/null +++ b/tools/qt/simulator/drivers/display/gui_thread.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef GRAPHIC_LITE_GUI_THREAD_H +#define GRAPHIC_LITE_GUI_THREAD_H + +#include +#include +#include "common/task_manager.h" +#include "monitor.h" + +namespace OHOS { +class GUIThread : public QThread { + Q_OBJECT +public: + GUIThread(QObject* parent); + virtual ~GUIThread(); + void run() override; + void Quit(); + Monitor* GetMonitor() + { + return monitor_; + }; + +private: + Monitor* monitor_; +}; +} // namespace OHOS + +#endif // GRAPHIC_LITE_GUI_THREAD_H diff --git a/tools/qt/simulator/drivers/display/monitor.cpp b/tools/qt/simulator/drivers/display/monitor.cpp new file mode 100755 index 0000000..394266c --- /dev/null +++ b/tools/qt/simulator/drivers/display/monitor.cpp @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "monitor.h" +#include "common/graphic_startup.h" +#include "common/image_decode_ability.h" +#include "common/input_device_manager.h" +#include "dock/screen_device_proxy.h" +#include "font/ui_font.h" +#include "font/ui_font_header.h" +#include "font/ui_font_vector.h" +#include "mousewheel_input.h" +#include "mouse_input.h" + +namespace OHOS { +void Monitor::Flush(int16_t x1, int16_t y1, int16_t x2, int16_t y2, const uint8_t* buffer, ColorMode mode) +{ + if (buffer == nullptr) { + ScreenDeviceProxy::GetInstance()->OnFlushReady(); + return; + } + + if ((x1 < 0) || (y1 < 0) || (x2 > HORIZONTAL_RESOLUTION - 1) || (y2 > VERTICAL_RESOLUTION - 1)) { + ScreenDeviceProxy::GetInstance()->OnFlushReady(); + return; + } + + int32_t x, y; + if (mode == ARGB8888) { + const Color32* tmp = reinterpret_cast(buffer); + for (y = y1; y <= y2; y++) { + for (x = x1; x <= x2; x++) { + tftFb_[y * HORIZONTAL_RESOLUTION + x] = tmp->full; + tmp++; + } + } + } + ScreenDeviceProxy::GetInstance()->OnFlushReady(); +} + +void Monitor::InitHal() +{ + ScreenDeviceProxy::GetInstance()->SetScreenSize(HORIZONTAL_RESOLUTION, VERTICAL_RESOLUTION); +#if ENABLE_FRAME_BUFFER + ScreenDeviceProxy::GetInstance()->SetFramebuffer(reinterpret_cast(tftFb_), ARGB8888, + HORIZONTAL_RESOLUTION); +#endif + ScreenDeviceProxy::GetInstance()->SetAnimatorbuffer(reinterpret_cast(animaterBuffer_), ARGB8888, + HORIZONTAL_RESOLUTION); + Monitor* display = Monitor::GetInstance(); + ScreenDeviceProxy::GetInstance()->SetDevice(display); + +#if USE_MOUSE + MouseInput* mouse = MouseInput::GetInstance(); + InputDeviceManager::GetInstance()->Add(mouse); +#endif + +#if USE_MOUSEWHEEL && ENABLE_ROTATE_INPUT + MousewheelInput* mousewheel = MousewheelInput::GetInstance(); + InputDeviceManager::GetInstance()->Add(mousewheel); +#endif +} + +void Monitor::RenderFinish() +{ + UpdatePaint(tftFb_, HORIZONTAL_RESOLUTION, VERTICAL_RESOLUTION); +} + +// assuming below are the memory pool +static uint8_t g_fontPsramBaseAddr[OHOS::MIN_FONT_PSRAM_LENGTH]; + +void Monitor::InitFontEngine() +{ + GraphicStartUp::InitFontEngine(reinterpret_cast(g_fontPsramBaseAddr), MIN_FONT_PSRAM_LENGTH, + VECTOR_FONT_DIR, DEFAULT_VECTOR_FONT_FILENAME); +} + +void Monitor::InitImageDecodeAbility() +{ + uint32_t imageType = IMG_SUPPORT_BITMAP | OHOS::IMG_SUPPORT_JPEG | OHOS::IMG_SUPPORT_PNG; + ImageDecodeAbility::GetInstance().SetImageDecodeAbility(imageType); +} + +void Monitor::GUILoopStart() const +{ + Sleep(GUI_REFR_PERIOD); +} + +void Monitor::InitGUI() +{ + for (uint32_t i = 0; i < HORIZONTAL_RESOLUTION * VERTICAL_RESOLUTION; i++) { + tftFb_[i] = defaultColor_; + } + UpdatePaint(tftFb_, HORIZONTAL_RESOLUTION, VERTICAL_RESOLUTION); +} + +void Monitor::GUILoopQuit() const {} +} // namespace OHOS diff --git a/tools/qt/simulator/drivers/display/monitor.h b/tools/qt/simulator/drivers/display/monitor.h new file mode 100755 index 0000000..2683f28 --- /dev/null +++ b/tools/qt/simulator/drivers/display/monitor.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef GRAPHIC_LITE_MONITOR_H +#define GRAPHIC_LITE_MONITOR_H + +#include +#include "dock/screen_device.h" +#include "font/ui_font_header.h" + +namespace OHOS { +class Monitor : public QObject, public ScreenDevice { + Q_OBJECT +public: + Monitor() : defaultColor_ (0x44) {} + virtual ~Monitor() {} + static Monitor* GetInstance() + { + static Monitor instance; + return &instance; + } + void Flush(int16_t x1, int16_t y1, int16_t x2, int16_t y2, const uint8_t* buffer, ColorMode mode) override; + void InitHal(); + void InitFontEngine(); + void InitImageDecodeAbility(); + void InitGUI(); + void GUILoopStart() const; + void GUIRefresh(); + void GUILoopQuit() const; + void RenderFinish() override; +signals: + void UpdatePaintSignal(uint32_t* tftFb, uint32_t imgWidth, uint32_t imgHeight); + +protected: + void UpdatePaint(uint32_t* tftFb, uint32_t imgWidth, uint32_t imgHeight) + { + emit UpdatePaintSignal(tftFb, imgWidth, imgHeight); + } + +private: + static constexpr uint32_t GUI_REFR_PERIOD = 50; /* ms */ + uint8_t fontPsramBaseAddr_[MIN_FONT_PSRAM_LENGTH]; + uint32_t tftFb_[HORIZONTAL_RESOLUTION * VERTICAL_RESOLUTION]; + uint32_t animaterBuffer_[HORIZONTAL_RESOLUTION * VERTICAL_RESOLUTION]; + uint32_t defaultColor_; +}; +} // namespace OHOS + +#endif // GRAPHIC_LITE_MONITOR_H diff --git a/tools/qt/simulator/drivers/display/task_thread.cpp b/tools/qt/simulator/drivers/display/task_thread.cpp new file mode 100755 index 0000000..31baedd --- /dev/null +++ b/tools/qt/simulator/drivers/display/task_thread.cpp @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "task_thread.h" + +namespace OHOS { +void TaskThread::run() +{ + taskQuitQry = false; + while (!taskQuitQry) { + TaskManager::GetInstance()->TaskHandler(); + Sleep(DEFAULT_TASK_PERIOD); + } +} + +void TaskThread::Quit() +{ + taskQuitQry = true; +} +} // namespace OHOS diff --git a/tools/qt/simulator/drivers/display/task_thread.h b/tools/qt/simulator/drivers/display/task_thread.h new file mode 100755 index 0000000..6ee4bf8 --- /dev/null +++ b/tools/qt/simulator/drivers/display/task_thread.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef GRAPHIC_LITE_TASK_THREAD_H +#define GRAPHIC_LITE_TASK_THREAD_H + +#include +#include +#include "common/task_manager.h" + +namespace OHOS { +class TaskThread : public QThread { +public: + TaskThread() {} + virtual ~TaskThread() {} + void run() override; + void Quit(); + +private: + volatile bool taskQuitQry = false; +}; +} // namespace OHOS + +#endif // GRAPHIC_LITE_TASK_THREAD_H diff --git a/tools/qt/simulator/drivers/indev/mouse_input.cpp b/tools/qt/simulator/drivers/indev/mouse_input.cpp new file mode 100755 index 0000000..ef754ed --- /dev/null +++ b/tools/qt/simulator/drivers/indev/mouse_input.cpp @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "mouse_input.h" +#include +#include + +namespace OHOS { +#if USE_MOUSE +bool MouseInput::Read(DeviceData& data) +{ + data.point.x = lastX_; + data.point.y = lastY_; + data.state = leftButtonDown_ ? STATE_PRESS : STATE_RELEASE; + return false; +} + +void MouseInput::MouseHandler(QMouseEvent* event) +{ + if (event == nullptr) { + return; + } + switch (event->type()) { + case QMouseEvent::Type::MouseButtonRelease: + if (event->button() == Qt::LeftButton) { + leftButtonDown_ = false; + } + break; + case QMouseEvent::Type::MouseButtonPress: + if (event->button() == Qt::LeftButton) { + leftButtonDown_ = true; + lastX_ = event->x(); + lastY_ = event->y(); + } + break; + case QMouseEvent::Type::MouseMove: + lastX_ = event->x(); + lastY_ = event->y(); + break; + default: + break; + } +} +#endif +} // namespace OHOS diff --git a/tools/qt/simulator/drivers/indev/mouse_input.h b/tools/qt/simulator/drivers/indev/mouse_input.h new file mode 100755 index 0000000..7b821ab --- /dev/null +++ b/tools/qt/simulator/drivers/indev/mouse_input.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef GRAPHIC_LITE_MOUSE_INPUT_H +#define GRAPHIC_LITE_MOUSE_INPUT_H + +#include +#include "config.h" +#include "dock/pointer_input_device.h" + +namespace OHOS { +#if USE_MOUSE +class MouseInput : public PointerInputDevice { +public: + MouseInput() : leftButtonDown_(false), lastX_(0), lastY_(0) {}; + virtual ~MouseInput() {}; + static MouseInput* GetInstance() + { + static MouseInput mouseInput; + return &mouseInput; + } + bool Read(DeviceData& data) override; + void MouseHandler(QMouseEvent* event); + +private: + bool leftButtonDown_; + int16_t lastX_; + int16_t lastY_; +}; +#endif // USE_MOUSE +} // namespace OHOS +#endif // GRAPHIC_LITE_MOUSE_INPUT_H diff --git a/tools/qt/simulator/drivers/indev/mousewheel_input.cpp b/tools/qt/simulator/drivers/indev/mousewheel_input.cpp new file mode 100755 index 0000000..026d618 --- /dev/null +++ b/tools/qt/simulator/drivers/indev/mousewheel_input.cpp @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ +#include "mousewheel_input.h" +#include +#include +#include + +static int16_t g_rotate = 0; + +namespace OHOS { +#if USE_MOUSEWHEEL +#if ENABLE_ROTATE_INPUT +bool MousewheelInput::Read(DeviceData &data) +{ + data.rotate = g_rotate; + g_rotate = 0; + return false; +} +void MousewheelInput::MousewheelHandler(QWheelEvent *event) +{ + g_rotate += -event->delta() / 120; // 120 : Qt use 120 as one mousewheel step value +} +#endif +#endif +} // namespace OHOS diff --git a/tools/qt/simulator/drivers/indev/mousewheel_input.h b/tools/qt/simulator/drivers/indev/mousewheel_input.h new file mode 100755 index 0000000..0553eca --- /dev/null +++ b/tools/qt/simulator/drivers/indev/mousewheel_input.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ +#ifndef MOUSEWHEEL_INPUT_H +#define MOUSEWHEEL_INPUT_H + +#include +#include "config.h" +#include "dock/rotate_input_device.h" + +namespace OHOS { +#if USE_MOUSEWHEEL +#if ENABLE_ROTATE_INPUT +class MousewheelInput : public RotateInputDevice { +public: + MousewheelInput() {} + virtual ~MousewheelInput() {} + static MousewheelInput* GetInstance() + { + static MousewheelInput mousewheelInput; + return &mousewheelInput; + } + bool Read(DeviceData& data) override; + void MousewheelHandler(QWheelEvent* event); +}; +#endif // USE_MOUSEWHEEL +#endif +} // namespace OHOS +#endif // MOUSEWHEEL_INPUT_H diff --git a/tools/qt/simulator/font/LICENSE.txt b/tools/qt/simulator/font/LICENSE.txt new file mode 100644 index 0000000..e730679 --- /dev/null +++ b/tools/qt/simulator/font/LICENSE.txt @@ -0,0 +1,96 @@ +Copyright -2020 Adobe (http://www.adobe.com/), with Reserved Font +Name 'Source'. Source is a trademark of Adobe in the United States +and/or other countries. + +This Font Software is licensed under the SIL Open Font License, +Version 1.1. + +This license is copied below, and is also available with a FAQ at: +http://scripts.sil.org/OFL + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font +creation efforts of academic and linguistic communities, and to +provide a free and open framework in which fonts may be shared and +improved in partnership with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply to +any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software +components as distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, +deleting, or substituting -- in part or in whole -- any of the +components of the Original Version, by changing formats or by porting +the Font Software to a new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, +modify, redistribute, and sell modified and unmodified copies of the +Font Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, in +Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the +corresponding Copyright Holder. This restriction only applies to the +primary font name as presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created using +the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/tools/qt/simulator/font/SourceHanSansSC-Regular.otf b/tools/qt/simulator/font/SourceHanSansSC-Regular.otf new file mode 100644 index 0000000..88e3a35 Binary files /dev/null and b/tools/qt/simulator/font/SourceHanSansSC-Regular.otf differ diff --git a/tools/qt/simulator/libui/libui.pro b/tools/qt/simulator/libui/libui.pro new file mode 100755 index 0000000..b673346 --- /dev/null +++ b/tools/qt/simulator/libui/libui.pro @@ -0,0 +1,259 @@ +CONFIG -= qt + +TEMPLATE = lib +CONFIG += staticlib + +CONFIG += c++11 + +# The following define makes your compiler emit warnings if you use +# any Qt feature that has been marked deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS + +DEFINES += QT_COMPILER + +# You can also make your code fail to compile if it uses deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + +DESTDIR = ../libs + +SOURCES += \ + ../../../../frameworks/animator/animator.cpp \ + ../../../../frameworks/animator/easing_equation.cpp \ + ../../../../frameworks/animator/interpolation.cpp \ + ../../../../frameworks/common/graphic_startup.cpp \ + ../../../../frameworks/common/image.cpp \ + ../../../../frameworks/common/input_device_manager.cpp \ + ../../../../frameworks/common/screen.cpp \ + ../../../../frameworks/common/screen_device_proxy.cpp \ + ../../../../frameworks/common/task.cpp \ + ../../../../frameworks/common/text.cpp \ + ../../../../frameworks/common/typed_text.cpp \ + ../../../../frameworks/common/ui_font_header.cpp \ + ../../../../frameworks/components/root_view.cpp \ + ../../../../frameworks/components/text_adapter.cpp \ + ../../../../frameworks/components/ui_abstract_clock.cpp \ + ../../../../frameworks/components/ui_abstract_progress.cpp \ + ../../../../frameworks/components/ui_abstract_scroll.cpp \ + ../../../../frameworks/components/ui_analog_clock.cpp \ + ../../../../frameworks/components/ui_arc_label.cpp \ + ../../../../frameworks/components/ui_axis.cpp \ + ../../../../frameworks/components/ui_box_progress.cpp \ + ../../../../frameworks/components/ui_button.cpp \ + ../../../../frameworks/components/ui_canvas.cpp \ + ../../../../frameworks/components/ui_chart.cpp \ + ../../../../frameworks/components/ui_checkbox.cpp \ + ../../../../frameworks/components/ui_circle_progress.cpp \ + ../../../../frameworks/components/ui_dialog.cpp \ + ../../../../frameworks/components/ui_digital_clock.cpp \ + ../../../../frameworks/components/ui_image_animator.cpp \ + ../../../../frameworks/components/ui_image_view.cpp \ + ../../../../frameworks/components/ui_label.cpp \ + ../../../../frameworks/components/ui_label_button.cpp \ + ../../../../frameworks/components/ui_list.cpp \ + ../../../../frameworks/components/ui_picker.cpp \ + ../../../../frameworks/components/ui_qrcode.cpp \ + ../../../../frameworks/components/ui_radio_button.cpp \ + ../../../../frameworks/components/ui_repeat_button.cpp \ + ../../../../frameworks/components/ui_scroll_view.cpp \ + ../../../../frameworks/components/ui_slider.cpp \ + ../../../../frameworks/components/ui_swipe_view.cpp \ + ../../../../frameworks/components/ui_texture_mapper.cpp \ + ../../../../frameworks/components/ui_time_picker.cpp \ + ../../../../frameworks/components/ui_toggle_button.cpp \ + ../../../../frameworks/components/ui_view.cpp \ + ../../../../frameworks/components/ui_view_group.cpp \ + ../../../../frameworks/core/render_manager.cpp \ + ../../../../frameworks/core/task_manager.cpp \ + ../../../../frameworks/default_resource/check_box_res.cpp \ + ../../../../frameworks/dfx/event_injector.cpp \ + ../../../../frameworks/dfx/key_event_injector.cpp \ + ../../../../frameworks/dfx/point_event_injector.cpp \ + ../../../../frameworks/dfx/ui_dump_dom_tree.cpp \ + ../../../../frameworks/dock/input_device.cpp \ + ../../../../frameworks/dock/key_input_device.cpp \ + ../../../../frameworks/dock/pointer_input_device.cpp \ + ../../../../frameworks/dock/rotate_input_device.cpp \ + ../../../../frameworks/dock/virtual_input_device.cpp \ + ../../../../frameworks/draw/draw_arc.cpp \ + ../../../../frameworks/draw/draw_curve.cpp \ + ../../../../frameworks/draw/draw_image.cpp \ + ../../../../frameworks/draw/draw_label.cpp \ + ../../../../frameworks/draw/draw_line.cpp \ + ../../../../frameworks/draw/draw_rect.cpp \ + ../../../../frameworks/draw/draw_triangle.cpp \ + ../../../../frameworks/draw/draw_utils.cpp \ + ../../../../frameworks/events/event.cpp \ + ../../../../frameworks/font/base_font.cpp \ + ../../../../frameworks/font/glyphs_manager.cpp \ + ../../../../frameworks/font/ui_font.cpp \ + ../../../../frameworks/font/ui_font_adaptor.cpp \ + ../../../../frameworks/font/ui_font_allocator.cpp \ + ../../../../frameworks/font/ui_font_cache.cpp \ + ../../../../frameworks/font/ui_font_vector.cpp \ + ../../../../frameworks/font/ui_line_break.cpp \ + ../../../../frameworks/font/ui_multi_font_manager.cpp \ + ../../../../frameworks/font/ui_text_shaping.cpp \ + ../../../../frameworks/imgdecode/cache_manager.cpp \ + ../../../../frameworks/imgdecode/file_img_decoder.cpp \ + ../../../../frameworks/imgdecode/image_load.cpp \ + ../../../../frameworks/layout/flex_layout.cpp \ + ../../../../frameworks/layout/grid_layout.cpp \ + ../../../../frameworks/layout/list_layout.cpp \ + ../../../../frameworks/themes/theme.cpp \ + ../../../../frameworks/themes/theme_manager.cpp \ + ../../../../../utils/frameworks/color.cpp \ + ../../../../../utils/frameworks/geometry2d.cpp \ + ../../../../../utils/frameworks/graphic_math.cpp \ + ../../../../../utils/frameworks/hal_tick.cpp \ + ../../../../../utils/frameworks/mem_api.cpp \ + ../../../../../utils/frameworks/style.cpp \ + ../../../../../utils/frameworks/sys_info.cpp \ + ../../../../../utils/frameworks/transform.cpp \ + ../../../../../utils/frameworks/version.cpp \ + ../../../../../../../third_party/bounds_checking_function/src/memset_s.c \ + ../../../../../../../third_party/cJSON/cJSON.c + +HEADERS += \ + ../../../../../surface/interfaces/kits/surface.h \ + ../../../../frameworks/common/typed_text.h \ + ../../../../frameworks/core/render_manager.h \ + ../../../../frameworks/default_resource/check_box_res.h \ + ../../../../frameworks/dfx/key_event_injector.h \ + ../../../../frameworks/dfx/point_event_injector.h \ + ../../../../frameworks/dock/input_device.h \ + ../../../../frameworks/dock/pointer_input_device.h \ + ../../../../frameworks/dock/screen_device.h \ + ../../../../frameworks/dock/screen_device_proxy.h \ + ../../../../frameworks/dock/virtual_input_device.h \ + ../../../../frameworks/draw/draw_arc.h \ + ../../../../frameworks/draw/draw_curve.h \ + ../../../../frameworks/draw/draw_image.h \ + ../../../../frameworks/draw/draw_label.h \ + ../../../../frameworks/draw/draw_line.h \ + ../../../../frameworks/draw/draw_rect.h \ + ../../../../frameworks/draw/draw_triangle.h \ + ../../../../frameworks/draw/draw_utils.h \ + ../../../../frameworks/font/ui_font_adaptor.h \ + ../../../../frameworks/font/ui_multi_font_manager.h \ + ../../../../frameworks/imgdecode/cache_manager.h \ + ../../../../frameworks/imgdecode/file_img_decoder.h \ + ../../../../frameworks/imgdecode/image_load.h \ + ../../../../interfaces/innerkits/common/graphic_startup.h \ + ../../../../interfaces/innerkits/common/image_decode_ability.h \ + ../../../../interfaces/innerkits/common/input_device_manager.h \ + ../../../../interfaces/innerkits/common/task_manager.h \ + ../../../../interfaces/innerkits/dock/focus_manager.h \ + ../../../../interfaces/innerkits/dock/rotate_input_device.h \ + ../../../../interfaces/kits/animator/animator.h \ + ../../../../interfaces/kits/animator/easing_equation.h \ + ../../../../interfaces/kits/animator/interpolation.h \ + ../../../../interfaces/kits/common/image.h \ + ../../../../interfaces/kits/common/screen.h \ + ../../../../interfaces/kits/common/task.h \ + ../../../../interfaces/kits/common/text.h \ + ../../../../interfaces/kits/components/abstract_adapter.h \ + ../../../../interfaces/kits/components/root_view.h \ + ../../../../interfaces/kits/components/text_adapter.h \ + ../../../../interfaces/kits/components/ui_abstract_clock.h \ + ../../../../interfaces/kits/components/ui_abstract_progress.h \ + ../../../../interfaces/kits/components/ui_abstract_scroll.h \ + ../../../../interfaces/kits/components/ui_analog_clock.h \ + ../../../../interfaces/kits/components/ui_arc_label.h \ + ../../../../interfaces/kits/components/ui_axis.h \ + ../../../../interfaces/kits/components/ui_box_progress.h \ + ../../../../interfaces/kits/components/ui_button.h \ + ../../../../interfaces/kits/components/ui_canvas.h \ + ../../../../interfaces/kits/components/ui_chart.h \ + ../../../../interfaces/kits/components/ui_checkbox.h \ + ../../../../interfaces/kits/components/ui_circle_progress.h \ + ../../../../interfaces/kits/components/ui_dialog.h \ + ../../../../interfaces/kits/components/ui_digital_clock.h \ + ../../../../interfaces/kits/components/ui_image_animator.h \ + ../../../../interfaces/kits/components/ui_image_view.h \ + ../../../../interfaces/kits/components/ui_label.h \ + ../../../../interfaces/kits/components/ui_label_button.h \ + ../../../../interfaces/kits/components/ui_list.h \ + ../../../../interfaces/kits/components/ui_picker.h \ + ../../../../interfaces/kits/components/ui_qrcode.h \ + ../../../../interfaces/kits/components/ui_radio_button.h \ + ../../../../interfaces/kits/components/ui_repeat_button.h \ + ../../../../interfaces/kits/components/ui_scroll_view.h \ + ../../../../interfaces/kits/components/ui_slider.h \ + ../../../../interfaces/kits/components/ui_swipe_view.h \ + ../../../../interfaces/kits/components/ui_texture_mapper.h \ + ../../../../interfaces/kits/components/ui_time_picker.h \ + ../../../../interfaces/kits/components/ui_toggle_button.h \ + ../../../../interfaces/kits/components/ui_view.h \ + ../../../../interfaces/kits/components/ui_view_group.h \ + ../../../../interfaces/kits/dfx/event_injector.h \ + ../../../../interfaces/kits/dfx/ui_dump_dom_tree.h \ + ../../../../interfaces/kits/events/aod_callback.h \ + ../../../../interfaces/kits/events/cancel_event.h \ + ../../../../interfaces/kits/events/click_event.h \ + ../../../../interfaces/kits/events/drag_event.h \ + ../../../../interfaces/kits/events/event.h \ + ../../../../interfaces/kits/events/long_press_event.h \ + ../../../../interfaces/kits/events/press_event.h \ + ../../../../interfaces/kits/events/release_event.h \ + ../../../../interfaces/kits/events/virtual_device_event.h \ + ../../../../interfaces/kits/font/ui_font.h \ + ../../../../interfaces/kits/font/ui_font_header.h \ + ../../../../interfaces/kits/layout/flex_layout.h \ + ../../../../interfaces/kits/layout/grid_layout.h \ + ../../../../interfaces/kits/layout/layout.h \ + ../../../../interfaces/kits/layout/list_layout.h \ + ../../../../interfaces/kits/themes/theme.h \ + ../../../../interfaces/kits/themes/theme_manager.h \ + ../../../../interfaces/kits/window/window.h \ + ../../../../../utils/interfaces/innerkits/graphic_config.h \ + ../../../../../utils/interfaces/innerkits/graphic_locker.h \ + ../../../../../utils/interfaces/innerkits/graphic_semaphore.h \ + ../../../../../utils/interfaces/innerkits/hal_tick.h \ + ../../../../../utils/interfaces/kits/color.h \ + ../../../../../utils/interfaces/kits/file.h \ + ../../../../../utils/interfaces/kits/geometry2d.h \ + ../../../../../utils/interfaces/kits/graphic_assert.h \ + ../../../../../utils/interfaces/kits/graphic_log.h \ + ../../../../../utils/interfaces/kits/graphic_math.h \ + ../../../../../utils/interfaces/kits/graphic_types.h \ + ../../../../../utils/interfaces/kits/heap_base.h \ + ../../../../../utils/interfaces/kits/image_info.h \ + ../../../../../utils/interfaces/kits/input_event_info.h \ + ../../../../../utils/interfaces/kits/list.h \ + ../../../../../utils/interfaces/kits/mem_api.h \ + ../../../../../utils/interfaces/kits/rect.h \ + ../../../../../utils/interfaces/kits/style.h \ + ../../../../../utils/interfaces/kits/sys_info.h \ + ../../../../../utils/interfaces/kits/transform.h \ + ../../../../../utils/interfaces/kits/version.h \ + ../../../../../wms/interfaces/innerkits/lite_wm_type.h \ + ../../../../../../../third_party/bounds_checking_function/include/securec.h \ + ../../../../../../../third_party/bounds_checking_function/include/securectype.h \ + ../../../../../../../third_party/bounds_checking_function/src/input.inl \ + ../../../../../../../third_party/bounds_checking_function/src/output.inl \ + ../../../../../../../third_party/bounds_checking_function/src/secinput.h \ + ../../../../../../../third_party/bounds_checking_function/src/securecutil.h \ + ../../../../../../../third_party/bounds_checking_function/src/secureprintoutput.h \ + ../../../../../../../third_party/cJSON/cJSON.h \ + ../../../../../../../third_party/cJSON/cJSON_Utils.h \ + ../../../../../../../tools/developer_tools_lite/graphic_tool/iar_project/config/gpu_2d/graphic_config.h + +INCLUDEPATH += \ + ../../../../frameworks \ + ../../../../../utils/frameworks/windows \ + ../../../../../utils/interfaces/innerkits \ + ../../../../../utils/interfaces/kits \ + ../../../../../ui/interfaces/innerkits \ + ../../../../../ui/interfaces/kits \ + ../../../../../../../third_party/bounds_checking_function/include \ + ../../../../../../../third_party/harfbuzz/src \ + ../../../../../../../third_party/icu/icu4c/source/common \ + ../../../../../../../third_party/freetype/include \ + ../../../../../../../third_party/cJSON \ + ../../../../../../../third_party/libjpeg \ + ../../../../../../../third_party/libpng \ + ../../../../../../../third_party/qrcodegen/cpp diff --git a/tools/qt/simulator/simulator.pro b/tools/qt/simulator/simulator.pro new file mode 100644 index 0000000..a249c99 --- /dev/null +++ b/tools/qt/simulator/simulator.pro @@ -0,0 +1,15 @@ +TEMPLATE = subdirs + +CONFIG += ordered + +SUBDIRS += \ + third_party/freetype \ + third_party/harfbuzz \ + third_party/icu \ + third_party/libjpeg \ + third_party/zlib \ + third_party/libpng \ + third_party/qrcodegen \ + libui \ + test \ + uitest/UITest.pro diff --git a/tools/qt/simulator/test/test.pro b/tools/qt/simulator/test/test.pro new file mode 100644 index 0000000..ae22e0f --- /dev/null +++ b/tools/qt/simulator/test/test.pro @@ -0,0 +1,128 @@ +CONFIG -= qt + +TEMPLATE = lib +CONFIG += staticlib + +CONFIG += c++11 + +# The following define makes your compiler emit warnings if you use +# any Qt feature that has been marked deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS + +DEFINES += QT_COMPILER + +# You can also make your code fail to compile if it uses deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + +DESTDIR = ../libs + +SOURCES += \ + ../../../../test/framework/src/test_case_list_adapter.cpp \ + ../../../../test/framework/src/ui_test_group.cpp \ + ../../../../test/framework/src/test_ability.cpp \ + ../../../../test/framework/src/ui_test_app.cpp \ + ../../../../test/uitest/test_animator/ui_test_animator.cpp \ + ../../../../test/uitest/test_anti_aliasing/ui_test_anti_aliasing.cpp \ + ../../../../test/uitest/test_arc_label/ui_test_arc_label.cpp \ + ../../../../test/uitest/test_button/ui_test_button.cpp \ + ../../../../test/uitest/test_canvas/ui_test_canvas.cpp \ + ../../../../test/uitest/test_chart/ui_test_chart_pillar.cpp \ + ../../../../test/uitest/test_chart/ui_test_chart_polyline.cpp \ + ../../../../test/uitest/test_dialog/ui_test_dialog.cpp \ + ../../../../test/uitest/test_digital_clock/ui_test_digital_clock.cpp \ + ../../../../test/uitest/test_draw_line/ui_test_draw_line.cpp \ + ../../../../test/uitest/test_draw_rect/ui_test_draw_rect.cpp \ + ../../../../test/uitest/test_event_injector/ui_test_event_injector.cpp \ + ../../../../test/uitest/test_font/ui_test_font.cpp \ + ../../../../test/uitest/test_image/ui_test_image.cpp \ + ../../../../test/uitest/test_image_animator/ui_test_image_animator.cpp \ + ../../../../test/uitest/test_input_event/ui_test_input_event.cpp \ + ../../../../test/uitest/test_label/ui_test_label.cpp \ + ../../../../test/uitest/test_layout/ui_test_advanced_layout.cpp \ + ../../../../test/uitest/test_layout/ui_test_basic_layout.cpp \ + ../../../../test/uitest/test_opacity/ui_test_opacity.cpp \ + ../../../../test/uitest/test_picker/ui_test_ui_picker.cpp \ + ../../../../test/uitest/test_progress_bar/ui_test_box_progress.cpp \ + ../../../../test/uitest/test_progress_bar/ui_test_circle_progress.cpp \ + ../../../../test/uitest/test_qrcode/ui_test_qrcode.cpp \ + ../../../../test/uitest/test_render/ui_test_render.cpp \ + ../../../../test/uitest/test_rotate_input/ui_test_rotate_input.cpp \ + ../../../../test/uitest/test_slider/ui_test_slider.cpp \ + ../../../../test/uitest/test_texture_mapper/ui_test_texture_mapper.cpp \ + ../../../../test/uitest/test_transform/ui_test_transform.cpp \ + ../../../../test/uitest/test_ui_analog_clock/ui_test_analog_clock.cpp \ + ../../../../test/uitest/test_ui_dump_dom_tree/ui_test_dump_dom.cpp \ + ../../../../test/uitest/test_ui_list/ui_test_ui_list.cpp \ + ../../../../test/uitest/test_ui_list_view/ui_test_list_layout.cpp \ + ../../../../test/uitest/test_ui_scroll_view/ui_test_ui_scroll_view.cpp \ + ../../../../test/uitest/test_ui_swipe_view/ui_test_ui_swipe_view.cpp \ + ../../../../test/uitest/test_vector_font/ui_test_vector_font.cpp \ + ../../../../test/uitest/test_view_percent/ui_test_view_percent.cpp \ + ../../../../test/uitest/test_view_scale_rotate/ui_test_view_scale_rotate.cpp + +HEADERS += \ + ../../../../test/framework/include/test_case_list_adapter.h \ + ../../../../test/framework/include/ui_test_app.h \ + ../../../../test/framework/include/test_resource_config.h \ + ../../../../test/framework/include/ui_test.h \ + ../../../../test/framework/include/ui_test_group.h \ + ../../../../test/uitest/test_animator/ui_test_animator.h \ + ../../../../test/uitest/test_anti_aliasing/ui_test_anti_aliasing.h \ + ../../../../test/uitest/test_arc_label/ui_test_arc_label.h \ + ../../../../test/uitest/test_button/ui_test_button.h \ + ../../../../test/uitest/test_canvas/ui_test_canvas.h \ + ../../../../test/uitest/test_chart/ui_test_chart_pillar.h \ + ../../../../test/uitest/test_chart/ui_test_chart_polyline.h \ + ../../../../test/uitest/test_dialog/ui_test_dialog.h \ + ../../../../test/uitest/test_digital_clock/ui_test_digital_clock.h \ + ../../../../test/uitest/test_draw_line/ui_test_draw_line.h \ + ../../../../test/uitest/test_draw_rect/ui_test_draw_rect.h \ + ../../../../test/uitest/test_event_injector/ui_test_event_injector.h \ + ../../../../test/uitest/test_font/ui_test_font.h \ + ../../../../test/uitest/test_image/ui_test_image.h \ + ../../../../test/uitest/test_image_animator/ui_test_image_animator.h \ + ../../../../test/uitest/test_input_event/ui_test_input_event.h \ + ../../../../test/uitest/test_label/ui_test_label.h \ + ../../../../test/uitest/test_layout/ui_test_advanced_layout.h \ + ../../../../test/uitest/test_layout/ui_test_basic_layout.h \ + ../../../../test/uitest/test_opacity/ui_test_opacity.h \ + ../../../../test/uitest/test_picker/ui_test_ui_picker.h \ + ../../../../test/uitest/test_progress_bar/ui_test_box_progress.h \ + ../../../../test/uitest/test_progress_bar/ui_test_circle_progress.h \ + ../../../../test/uitest/test_qrcode/ui_test_qrcode.cpp \ + ../../../../test/uitest/test_render/ui_test_render.h \ + ../../../../test/uitest/test_rotate_input/ui_test_rotate_input.h \ + ../../../../test/uitest/test_slider/ui_test_slider.h \ + ../../../../test/uitest/test_texture_mapper/ui_test_texture_mapper.h \ + ../../../../test/uitest/test_transform/ui_test_transform.h \ + ../../../../test/uitest/test_ui_analog_clock/ui_test_analog_clock.h \ + ../../../../test/uitest/test_ui_dump_dom_tree/ui_test_dump_dom.h \ + ../../../../test/uitest/test_ui_list/ui_test_ui_list.h \ + ../../../../test/uitest/test_ui_list_view/ui_test_list_layout.h \ + ../../../../test/uitest/test_ui_scroll_view/ui_test_ui_scroll_view.h \ + ../../../../test/uitest/test_ui_swipe_view/ui_test_ui_swipe_view.h \ + ../../../../test/uitest/test_vector_font/ui_test_vector_font.h \ + ../../../../test/uitest/test_view_percent/ui_test_view_percent.h \ + ../../../../test/uitest/test_view_scale_rotate/ui_test_view_scale_rotate.h + +INCLUDEPATH += \ + ../../../../frameworks \ + ../../../../../utils/frameworks/windows \ + ../../../../../utils/interfaces/innerkits \ + ../../../../../utils/interfaces/kits \ + ../../../../../ui/interfaces/frameworks \ + ../../../../../ui/interfaces/innerkits \ + ../../../../../ui/interfaces/kits \ + ../../../../test/framework/include \ + ../../../../test/uitest \ + ../../../../../../../third_party/bounds_checking_function/include \ + ../../../../../../../third_party/harfbuzz/src \ + ../../../../../../../third_party/icu/icu4c/source/common \ + ../../../../../../../third_party/freetype/include \ + ../../../../../../../third_party/cJSON \ + ../../../../../../../third_party/libjpeg \ + ../../../../../../../third_party/libpng diff --git a/tools/qt/simulator/third_party/freetype/freetype.pro b/tools/qt/simulator/third_party/freetype/freetype.pro new file mode 100644 index 0000000..e96f187 --- /dev/null +++ b/tools/qt/simulator/third_party/freetype/freetype.pro @@ -0,0 +1,66 @@ +CONFIG -= qt + +TEMPLATE = lib +CONFIG += staticlib + +CONFIG += c++11 + +# The following define makes your compiler emit warnings if you use +# any Qt feature that has been marked deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS \ + FT2_BUILD_LIBRARY \ + FT_DEBUG_LEVEL_ERROR \ + FT_DEBUG_LEVEL_TRACE \ + +# You can also make your code fail to compile if it uses deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + +DESTDIR = ../../libs + +SOURCES += \ + ../../../../../../../../third_party/freetype/src/autofit/autofit.c \ + ../../../../../../../../third_party/freetype/src/base/ftbase.c \ + ../../../../../../../../third_party/freetype/src/base/ftbbox.c \ + ../../../../../../../../third_party/freetype/src/base/ftbdf.c \ + ../../../../../../../../third_party/freetype/src/base/ftbitmap.c \ + ../../../../../../../../third_party/freetype/src/base/ftcid.c \ + ../../../../../../../../third_party/freetype/src/base/ftfstype.c \ + ../../../../../../../../third_party/freetype/src/base/ftgasp.c \ + ../../../../../../../../third_party/freetype/src/base/ftglyph.c \ + ../../../../../../../../third_party/freetype/src/base/ftgxval.c \ + ../../../../../../../../third_party/freetype/src/base/ftinit.c \ + ../../../../../../../../third_party/freetype/src/base/ftmm.c \ + ../../../../../../../../third_party/freetype/src/base/ftotval.c \ + ../../../../../../../../third_party/freetype/src/base/ftpatent.c \ + ../../../../../../../../third_party/freetype/src/base/ftpfr.c \ + ../../../../../../../../third_party/freetype/src/base/ftstroke.c \ + ../../../../../../../../third_party/freetype/src/base/ftsynth.c \ + ../../../../../../../../third_party/freetype/src/base/ftsystem.c \ + ../../../../../../../../third_party/freetype/src/base/fttype1.c \ + ../../../../../../../../third_party/freetype/src/base/ftwinfnt.c \ + ../../../../../../../../third_party/freetype/src/bdf/bdf.c \ + ../../../../../../../../third_party/freetype/src/cache/ftcache.c \ + ../../../../../../../../third_party/freetype/src/cff/cff.c \ + ../../../../../../../../third_party/freetype/src/cid/type1cid.c \ + ../../../../../../../../third_party/freetype/src/gzip/ftgzip.c \ + ../../../../../../../../third_party/freetype/src/lzw/ftlzw.c \ + ../../../../../../../../third_party/freetype/src/pcf/pcf.c \ + ../../../../../../../../third_party/freetype/src/pfr/pfr.c \ + ../../../../../../../../third_party/freetype/src/psaux/psaux.c \ + ../../../../../../../../third_party/freetype/src/pshinter/pshinter.c \ + ../../../../../../../../third_party/freetype/src/psnames/psmodule.c \ + ../../../../../../../../third_party/freetype/src/raster/raster.c \ + ../../../../../../../../third_party/freetype/src/sfnt/sfnt.c \ + ../../../../../../../../third_party/freetype/src/smooth/smooth.c \ + ../../../../../../../../third_party/freetype/src/truetype/truetype.c \ + ../../../../../../../../third_party/freetype/src/type1/type1.c \ + ../../../../../../../../third_party/freetype/src/type42/type42.c \ + ../../../../../../../../third_party/freetype/src/winfonts/winfnt.c \ + ../../../../../../../../third_party/freetype/builds/windows/ftdebug.c + +INCLUDEPATH += \ + ../../../../../../../../third_party/freetype/include diff --git a/tools/qt/simulator/third_party/harfbuzz/harfbuzz.pro b/tools/qt/simulator/third_party/harfbuzz/harfbuzz.pro new file mode 100644 index 0000000..8d2107d --- /dev/null +++ b/tools/qt/simulator/third_party/harfbuzz/harfbuzz.pro @@ -0,0 +1,72 @@ +CONFIG -= qt + +TEMPLATE = lib +CONFIG += staticlib + +CONFIG += c++11 + +# The following define makes your compiler emit warnings if you use +# any Qt feature that has been marked deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS + +# You can also make your code fail to compile if it uses deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + +DESTDIR = ../../libs + +SOURCES += \ + ../../../../../../../../third_party/harfbuzz/src/hb-aat-layout.cc \ + ../../../../../../../../third_party/harfbuzz/src/hb-aat-map.cc \ + ../../../../../../../../third_party/harfbuzz/src/hb-aat-layout.cc \ + ../../../../../../../../third_party/harfbuzz/src/hb-aat-map.cc \ + ../../../../../../../../third_party/harfbuzz/src/hb-blob.cc \ + ../../../../../../../../third_party/harfbuzz/src/hb-buffer-serialize.cc \ + ../../../../../../../../third_party/harfbuzz/src/hb-buffer.cc \ + ../../../../../../../../third_party/harfbuzz/src/hb-common.cc \ + ../../../../../../../../third_party/harfbuzz/src/hb-face.cc \ + ../../../../../../../../third_party/harfbuzz/src/hb-fallback-shape.cc \ + ../../../../../../../../third_party/harfbuzz/src/hb-font.cc \ + ../../../../../../../../third_party/harfbuzz/src/hb-map.cc \ + ../../../../../../../../third_party/harfbuzz/src/hb-ot-cff1-table.cc \ + ../../../../../../../../third_party/harfbuzz/src/hb-ot-cff2-table.cc \ + ../../../../../../../../third_party/harfbuzz/src/hb-ot-face.cc \ + ../../../../../../../../third_party/harfbuzz/src/hb-ot-font.cc \ + ../../../../../../../../third_party/harfbuzz/src/hb-ot-layout.cc \ + ../../../../../../../../third_party/harfbuzz/src/hb-ot-map.cc \ + ../../../../../../../../third_party/harfbuzz/src/hb-ot-math.cc \ + ../../../../../../../../third_party/harfbuzz/src/hb-ot-meta.cc \ + ../../../../../../../../third_party/harfbuzz/src/hb-ot-metrics.cc \ + ../../../../../../../../third_party/harfbuzz/src/hb-ot-name.cc \ + ../../../../../../../../third_party/harfbuzz/src/hb-ot-shape-complex-arabic.cc \ + ../../../../../../../../third_party/harfbuzz/src/hb-ot-shape-complex-default.cc \ + ../../../../../../../../third_party/harfbuzz/src/hb-ot-shape-complex-hangul.cc \ + ../../../../../../../../third_party/harfbuzz/src/hb-ot-shape-complex-hebrew.cc \ + ../../../../../../../../third_party/harfbuzz/src/hb-ot-shape-complex-indic-table.cc \ + ../../../../../../../../third_party/harfbuzz/src/hb-ot-shape-complex-indic.cc \ + ../../../../../../../../third_party/harfbuzz/src/hb-ot-shape-complex-khmer.cc \ + ../../../../../../../../third_party/harfbuzz/src/hb-ot-shape-complex-myanmar.cc \ + ../../../../../../../../third_party/harfbuzz/src/hb-ot-shape-complex-thai.cc \ + ../../../../../../../../third_party/harfbuzz/src/hb-ot-shape-complex-use-table.cc \ + ../../../../../../../../third_party/harfbuzz/src/hb-ot-shape-complex-use.cc \ + ../../../../../../../../third_party/harfbuzz/src/hb-ot-shape-complex-vowel-constraints.cc \ + ../../../../../../../../third_party/harfbuzz/src/hb-ot-shape-fallback.cc \ + ../../../../../../../../third_party/harfbuzz/src/hb-ot-shape-normalize.cc \ + ../../../../../../../../third_party/harfbuzz/src/hb-ot-shape.cc \ + ../../../../../../../../third_party/harfbuzz/src/hb-ot-tag.cc \ + ../../../../../../../../third_party/harfbuzz/src/hb-ot-var.cc \ + ../../../../../../../../third_party/harfbuzz/src/hb-set.cc \ + ../../../../../../../../third_party/harfbuzz/src/hb-shape-plan.cc \ + ../../../../../../../../third_party/harfbuzz/src/hb-shape.cc \ + ../../../../../../../../third_party/harfbuzz/src/hb-shaper.cc \ + ../../../../../../../../third_party/harfbuzz/src/hb-static.cc \ + ../../../../../../../../third_party/harfbuzz/src/hb-subset-cff2.cc \ + ../../../../../../../../third_party/harfbuzz/src/hb-subset-cff-common.cc \ + ../../../../../../../../third_party/harfbuzz/src/hb-ucd.cc \ + ../../../../../../../../third_party/harfbuzz/src/hb-unicode.cc + +INCLUDEPATH += \ + ../../../../../../../../third_party/harfbuzz/src diff --git a/tools/qt/simulator/third_party/icu/icu.pro b/tools/qt/simulator/third_party/icu/icu.pro new file mode 100644 index 0000000..d6faab2 --- /dev/null +++ b/tools/qt/simulator/third_party/icu/icu.pro @@ -0,0 +1,36 @@ +CONFIG -= qt + +TEMPLATE = lib +CONFIG += staticlib + +CONFIG += c++11 + +# The following define makes your compiler emit warnings if you use +# any Qt feature that has been marked deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS + +# You can also make your code fail to compile if it uses deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + +DESTDIR = ../../libs + +SOURCES += \ + ../../../../../../../../third_party/icu/icu4c/source/common/cmemory.cpp \ + ../../../../../../../../third_party/icu/icu4c/source/common/cstring.cpp \ + ../../../../../../../../third_party/icu/icu4c/source/common/ubidi.cpp \ + ../../../../../../../../third_party/icu/icu4c/source/common/ubidi_props.cpp \ + ../../../../../../../../third_party/icu/icu4c/source/common/ubidiln.cpp \ + ../../../../../../../../third_party/icu/icu4c/source/common/ubidiwrt.cpp \ + ../../../../../../../../third_party/icu/icu4c/source/common/uchar.cpp \ + ../../../../../../../../third_party/icu/icu4c/source/common/udataswp.cpp \ + ../../../../../../../../third_party/icu/icu4c/source/common/uinvchar.cpp \ + ../../../../../../../../third_party/icu/icu4c/source/common/ustring.cpp \ + ../../../../../../../../third_party/icu/icu4c/source/common/utf_impl.cpp \ + ../../../../../../../../third_party/icu/icu4c/source/common/utrie2.cpp + +INCLUDEPATH += \ + ../../../../../../../../third_party/icu/icu4c/source/common diff --git a/tools/qt/simulator/third_party/libjpeg/libjpeg.pro b/tools/qt/simulator/third_party/libjpeg/libjpeg.pro new file mode 100644 index 0000000..a69bcfd --- /dev/null +++ b/tools/qt/simulator/third_party/libjpeg/libjpeg.pro @@ -0,0 +1,90 @@ +CONFIG -= qt + +TEMPLATE = lib +CONFIG += staticlib + +CONFIG += c++11 + +# The following define makes your compiler emit warnings if you use +# any Qt feature that has been marked deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS + +# You can also make your code fail to compile if it uses deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + +DESTDIR = ../../libs + +SOURCES += \ + ../../../../../../../../third_party/libjpeg/cdjpeg.c \ + ../../../../../../../../third_party/libjpeg/cjpeg.c \ + ../../../../../../../../third_party/libjpeg/ckconfig.c \ + ../../../../../../../../third_party/libjpeg/djpeg.c \ + ../../../../../../../../third_party/libjpeg/jaricom.c \ + ../../../../../../../../third_party/libjpeg/jcapimin.c \ + ../../../../../../../../third_party/libjpeg/jcapistd.c \ + ../../../../../../../../third_party/libjpeg/jcarith.c \ + ../../../../../../../../third_party/libjpeg/jccoefct.c \ + ../../../../../../../../third_party/libjpeg/jccolor.c \ + ../../../../../../../../third_party/libjpeg/jcdctmgr.c \ + ../../../../../../../../third_party/libjpeg/jcinit.c \ + ../../../../../../../../third_party/libjpeg/jcmainct.c \ + ../../../../../../../../third_party/libjpeg/jcmarker.c \ + ../../../../../../../../third_party/libjpeg/jcmaster.c \ + ../../../../../../../../third_party/libjpeg/jcomapi.c \ + ../../../../../../../../third_party/libjpeg/jcparam.c \ + ../../../../../../../../third_party/libjpeg/jcprepct.c \ + ../../../../../../../../third_party/libjpeg/jcsample.c \ + ../../../../../../../../third_party/libjpeg/jctrans.c \ + ../../../../../../../../third_party/libjpeg/jdapimin.c \ + ../../../../../../../../third_party/libjpeg/jdapistd.c \ + ../../../../../../../../third_party/libjpeg/jdarith.c \ + ../../../../../../../../third_party/libjpeg/jdatadst.c \ + ../../../../../../../../third_party/libjpeg/jdatasrc.c \ + ../../../../../../../../third_party/libjpeg/jdcoefct.c \ + ../../../../../../../../third_party/libjpeg/jdcolor.c \ + ../../../../../../../../third_party/libjpeg/jddctmgr.c \ + ../../../../../../../../third_party/libjpeg/jdhuff.c \ + ../../../../../../../../third_party/libjpeg/jdinput.c \ + ../../../../../../../../third_party/libjpeg/jdmainct.c \ + ../../../../../../../../third_party/libjpeg/jdmarker.c \ + ../../../../../../../../third_party/libjpeg/jdmaster.c \ + ../../../../../../../../third_party/libjpeg/jdmerge.c \ + ../../../../../../../../third_party/libjpeg/jdpostct.c \ + ../../../../../../../../third_party/libjpeg/jdsample.c \ + ../../../../../../../../third_party/libjpeg/jdtrans.c \ + ../../../../../../../../third_party/libjpeg/jerror.c \ + ../../../../../../../../third_party/libjpeg/jfdctflt.c \ + ../../../../../../../../third_party/libjpeg/jfdctfst.c \ + ../../../../../../../../third_party/libjpeg/jfdctint.c \ + ../../../../../../../../third_party/libjpeg/jidctflt.c \ + ../../../../../../../../third_party/libjpeg/jidctfst.c \ + ../../../../../../../../third_party/libjpeg/jidctint.c \ + ../../../../../../../../third_party/libjpeg/jmemansi.c \ + ../../../../../../../../third_party/libjpeg/jmemmgr.c \ + ../../../../../../../../third_party/libjpeg/jmemnobs.c \ + ../../../../../../../../third_party/libjpeg/jpegtran.c \ + ../../../../../../../../third_party/libjpeg/jquant1.c \ + ../../../../../../../../third_party/libjpeg/jquant2.c \ + ../../../../../../../../third_party/libjpeg/jutils.c \ + ../../../../../../../../third_party/libjpeg/rdbmp.c \ + ../../../../../../../../third_party/libjpeg/rdcolmap.c \ + ../../../../../../../../third_party/libjpeg/rdgif.c \ + ../../../../../../../../third_party/libjpeg/rdjpgcom.c \ + ../../../../../../../../third_party/libjpeg/rdppm.c \ + ../../../../../../../../third_party/libjpeg/rdrle.c \ + ../../../../../../../../third_party/libjpeg/rdswitch.c \ + ../../../../../../../../third_party/libjpeg/rdtarga.c \ + ../../../../../../../../third_party/libjpeg/transupp.c \ + ../../../../../../../../third_party/libjpeg/wrbmp.c \ + ../../../../../../../../third_party/libjpeg/wrgif.c \ + ../../../../../../../../third_party/libjpeg/wrjpgcom.c \ + ../../../../../../../../third_party/libjpeg/wrppm.c \ + ../../../../../../../../third_party/libjpeg/wrrle.c \ + ../../../../../../../../third_party/libjpeg/wrtarga.c + +INCLUDEPATH += \ + ../../../../../../../third_party/libjpeg diff --git a/tools/qt/simulator/third_party/libpng/libpng.pro b/tools/qt/simulator/third_party/libpng/libpng.pro new file mode 100644 index 0000000..9522deb --- /dev/null +++ b/tools/qt/simulator/third_party/libpng/libpng.pro @@ -0,0 +1,41 @@ +CONFIG -= qt + +TEMPLATE = lib +CONFIG += staticlib + +CONFIG += c++11 + +# The following define makes your compiler emit warnings if you use +# any Qt feature that has been marked deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS + +# You can also make your code fail to compile if it uses deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + +DESTDIR = ../../libs + +SOURCES += \ + ../../../../../../../../third_party/libpng/png.c \ + ../../../../../../../../third_party/libpng/pngerror.c \ + ../../../../../../../../third_party/libpng/pngget.c \ + ../../../../../../../../third_party/libpng/pngmem.c \ + ../../../../../../../../third_party/libpng/pngpread.c \ + ../../../../../../../../third_party/libpng/pngread.c \ + ../../../../../../../../third_party/libpng/pngrio.c \ + ../../../../../../../../third_party/libpng/pngrtran.c \ + ../../../../../../../../third_party/libpng/pngrutil.c \ + ../../../../../../../../third_party/libpng/pngset.c \ + ../../../../../../../../third_party/libpng/pngtest.c \ + ../../../../../../../../third_party/libpng/pngtrans.c \ + ../../../../../../../../third_party/libpng/pngwio.c \ + ../../../../../../../../third_party/libpng/pngwrite.c \ + ../../../../../../../../third_party/libpng/pngwtran.c \ + ../../../../../../../../third_party/libpng/pngwutil.c + +INCLUDEPATH += \ + ../../../../../../../../third_party/libpng \ + ../../../../../../../../third_party/zlib diff --git a/tools/qt/simulator/third_party/qrcodegen/qrcodegen.pro b/tools/qt/simulator/third_party/qrcodegen/qrcodegen.pro new file mode 100644 index 0000000..b26c74c --- /dev/null +++ b/tools/qt/simulator/third_party/qrcodegen/qrcodegen.pro @@ -0,0 +1,25 @@ +CONFIG -= qt + +TEMPLATE = lib +CONFIG += staticlib + +CONFIG += c++11 + +# The following define makes your compiler emit warnings if you use +# any Qt feature that has been marked deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS + +# You can also make your code fail to compile if it uses deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + +DESTDIR = ../../libs + +SOURCES += \ + ../../../../../../../../third_party/qrcodegen/cpp/QrCode.cpp + +INCLUDEPATH += \ + ../../../../../../../../third_party/qrcodegen/cpp diff --git a/tools/qt/simulator/third_party/zlib/unistd.h b/tools/qt/simulator/third_party/zlib/unistd.h new file mode 100644 index 0000000..ae717cb --- /dev/null +++ b/tools/qt/simulator/third_party/zlib/unistd.h @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2021-2021 Huawei Device Co., Ltd. + * 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. + */ +#ifndef _UNISTD_H +#define _UNISTD_H +// Stub header for zlib project in qt +#endif \ No newline at end of file diff --git a/tools/qt/simulator/third_party/zlib/zlib.pro b/tools/qt/simulator/third_party/zlib/zlib.pro new file mode 100644 index 0000000..12fbcb3 --- /dev/null +++ b/tools/qt/simulator/third_party/zlib/zlib.pro @@ -0,0 +1,36 @@ +CONFIG -= qt + +TEMPLATE = lib +CONFIG += staticlib + +CONFIG += c++11 + +# The following define makes your compiler emit warnings if you use +# any Qt feature that has been marked deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS + +# You can also make your code fail to compile if it uses deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + +DESTDIR = ../../libs + +SOURCES += \ + ../../../../../../../../third_party/zlib/adler32.c \ + ../../../../../../../../third_party/zlib/compress.c \ + ../../../../../../../../third_party/zlib/crc32.c \ + ../../../../../../../../third_party/zlib/deflate.c \ + ../../../../../../../../third_party/zlib/infback.c \ + ../../../../../../../../third_party/zlib/inffast.c \ + ../../../../../../../../third_party/zlib/inflate.c \ + ../../../../../../../../third_party/zlib/inftrees.c \ + ../../../../../../../../third_party/zlib/trees.c \ + ../../../../../../../../third_party/zlib/uncompr.c \ + ../../../../../../../../third_party/zlib/zutil.c + +INCLUDEPATH += \ + . \ + ../../../../../../../../third_party/zlib diff --git a/tools/qt/simulator/uitest/UITest.pro b/tools/qt/simulator/uitest/UITest.pro new file mode 100644 index 0000000..b6bc017 --- /dev/null +++ b/tools/qt/simulator/uitest/UITest.pro @@ -0,0 +1,71 @@ + +QT += core gui network + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +CONFIG += c++11 + +# The following define makes your compiler emit warnings if you use +# any Qt feature that has been marked deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS + +DEFINES += QT_COMPILER + +# You can also make your code fail to compile if it uses deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + +DESTDIR = ../ + +FORMS += \ + main_widget.ui + +LIBS += -L$$DESTDIR/libs \ + -lfreetype \ + -lharfbuzz \ + -licu \ + -lzlib \ + -llibpng \ + -llibjpeg \ + -lqrcodegen \ + -llibui \ + -ltest + +TRANSLATIONS += helloqt_zh_CN.ts + +# Default rules for deployment. +qnx: target.path =/tmp/$${TARGET}/bin +else: unix:!android: target.path =/opt/$${TARGET}/bin +!isEmpty(target.path): INSTALLS += target + +SOURCES += \ + ../drivers/display/gui_thread.cpp \ + ../drivers/display/monitor.cpp \ + ../drivers/display/task_thread.cpp \ + ../drivers/indev/mouse_input.cpp \ + ../drivers/indev/mousewheel_input.cpp \ + main.cpp \ + main_widget.cpp + +HEADERS += \ + ../drivers/config.h \ + ../drivers/display/gui_thread.h \ + ../drivers/display/task_thread.h \ + ../drivers/display/monitor.h \ + ../drivers/indev/mouse_input.h \ + ../drivers/indev/mousewheel_input.h \ + main_widget.h + +INCLUDEPATH += \ + ../../../../frameworks \ + ../../../../../utils/interfaces/innerkits \ + ../../../../../utils/interfaces/kits \ + ../../../../../ui/interfaces/innerkits \ + ../../../../../ui/interfaces/kits \ + ../../../../../../../third_party/freetype/include \ + ../drivers/display \ + ../drivers/indev \ + ../drivers diff --git a/tools/qt/simulator/uitest/main.cpp b/tools/qt/simulator/uitest/main.cpp new file mode 100755 index 0000000..8d8443f --- /dev/null +++ b/tools/qt/simulator/uitest/main.cpp @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include + +#include "graphic_config.h" +#include "main_widget.h" +#include "monitor.h" + +extern void RunApp(); +int main(int argc, char* argv[]) +{ + QApplication uitest(argc, argv); + OHOS::GraphicStartUp::Init(); + OHOS::Monitor::GetInstance()->InitHal(); + OHOS::Monitor::GetInstance()->InitFontEngine(); + OHOS::Monitor::GetInstance()->InitImageDecodeAbility(); + RunApp(); + OHOS::MainWidget mainWidget; + mainWidget.resize(OHOS::HORIZONTAL_RESOLUTION, OHOS::VERTICAL_RESOLUTION); + mainWidget.show(); + return uitest.exec(); +} diff --git a/tools/qt/simulator/uitest/main_widget.cpp b/tools/qt/simulator/uitest/main_widget.cpp new file mode 100755 index 0000000..26adf34 --- /dev/null +++ b/tools/qt/simulator/uitest/main_widget.cpp @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#include "main_widget.h" +#include + +namespace OHOS { +MainWidget::MainWidget(QWidget* parent) : QWidget(parent), guiThread_(nullptr), taskThread_(nullptr) +{ + ui_->setupUi(this); + CreateGUIThread(); + CreateTaskThread(); +} + +MainWidget::~MainWidget() +{ + delete ui_; + if (guiThread_ != nullptr) { + guiThread_->Quit(); + guiThread_->wait(); + delete guiThread_; + } + if (taskThread_ != nullptr) { + taskThread_->Quit(); + taskThread_->wait(); + delete taskThread_; + } +} + +void MainWidget::CreateGUIThread() +{ + guiThread_ = new GUIThread(nullptr); + if (guiThread_ != nullptr) { + guiThread_->start(); + qRegisterMetaType("uint32_t"); + connect(guiThread_->GetMonitor(), SIGNAL(UpdatePaintSignal(uint32_t*, uint32_t, uint32_t)), this, + SLOT(UpdatePaintSlot(uint32_t*, uint32_t, uint32_t))); + } +} + +void MainWidget::CreateTaskThread() +{ + taskThread_ = new TaskThread(); + if (taskThread_ != nullptr) { + taskThread_->start(); + } +} + +void MainWidget::paintEvent(QPaintEvent* event) +{ + Q_UNUSED(event) + QPainter painter(this); + painter.drawImage(0, 0, img_); +} + +void MainWidget::mouseMoveEvent(QMouseEvent* event) +{ + MouseInput::GetInstance()->MouseHandler(event); +} + +void MainWidget::mousePressEvent(QMouseEvent* event) +{ +#if USE_MOUSE != 0 + MouseInput::GetInstance()->MouseHandler(event); +#endif +} + +void MainWidget::mouseReleaseEvent(QMouseEvent* event) +{ +#if USE_MOUSE != 0 + MouseInput::GetInstance()->MouseHandler(event); +#endif +} +void MainWidget::wheelEvent(QWheelEvent* event) +{ +#if USE_MOUSEWHEEL && ENABLE_ROTATE_INPUT + MousewheelInput::GetInstance()->MousewheelHandler(event); +#endif +} +} // namespace OHOS diff --git a/tools/qt/simulator/uitest/main_widget.h b/tools/qt/simulator/uitest/main_widget.h new file mode 100755 index 0000000..69ef4ca --- /dev/null +++ b/tools/qt/simulator/uitest/main_widget.h @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef GRAPHIC_LITE_MAIN_WIDGET_H +#define GRAPHIC_LITE_MAIN_WIDGET_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "common/graphic_startup.h" +#include "gui_thread.h" +#include "monitor.h" +#include "mouse_input.h" +#include "mousewheel_input.h" +#include "task_thread.h" +#include "ui_mainwidget.h" + +QT_BEGIN_NAMESPACE +namespace Ui { +class MainWidget; +} +QT_END_NAMESPACE + +namespace OHOS { +class MainWidget : public QWidget { + Q_OBJECT +public: + MainWidget(QWidget* parent = nullptr); + ~MainWidget(); + void CreateGUIThread(); + void CreateTaskThread(); + +protected: + void mouseMoveEvent(QMouseEvent* event) override; + void mousePressEvent(QMouseEvent* event) override; + void mouseReleaseEvent(QMouseEvent* event) override; + void wheelEvent(QWheelEvent* event) override; + void paintEvent(QPaintEvent* event) override; + +private: + Ui::MainWidget* ui_; + QImage img_; + uint32_t width_; + uint32_t height_; + GUIThread* guiThread_; + TaskThread* taskThread_; + +public slots: + void UpdatePaintSlot(uint32_t* tftFb, uint32_t imgWidth, uint32_t imgHeight) + { + img_ = QImage(imgWidth, imgHeight, QImage::Format_RGB32); + uint32_t* p = tftFb; + for (uint32_t i = 0; i < imgHeight; i++) { + for (uint32_t j = 0; j < imgWidth; j++) { + img_.setPixel(j, i, *p++); + } + } + update(); + }; +}; +} // namespace OHOS + +#endif // GRAPHIC_LITE_MAIN_WIDGET_H diff --git a/tools/qt/simulator/uitest/main_widget.ui b/tools/qt/simulator/uitest/main_widget.ui new file mode 100644 index 0000000..9573c7b --- /dev/null +++ b/tools/qt/simulator/uitest/main_widget.ui @@ -0,0 +1,33 @@ + + + + MainWidget + + + + 0 + 0 + 800 + 600 + + + + MainWidget + + + + + diff --git a/tools/qt/simulator/uitest/ui_mainwidget.h b/tools/qt/simulator/uitest/ui_mainwidget.h new file mode 100644 index 0000000..573ccbd --- /dev/null +++ b/tools/qt/simulator/uitest/ui_mainwidget.h @@ -0,0 +1,44 @@ +/******************************************************************************** + ** Form generated from reading UI file 'mainwidget.ui' + ** + ** Created by: Qt User Interface Compiler version 5.14.2 + ** + ** WARNING! All changes made in this file will be lost when recompiling UI file! +********************************************************************************/ + +#ifndef UI_MAINWIDGET_H +#define UI_MAINWIDGET_H + +#include +#include +#include + +QT_BEGIN_NAMESPACE + +class Ui_MainWidget { +public: + void setupUi(QWidget* MainWidget) + { + if (MainWidget->objectName().isEmpty()) + MainWidget->setObjectName(QString::fromUtf8("MainWidget")); + MainWidget->resize(800, 600); + + retranslateUi(MainWidget); + + QMetaObject::connectSlotsByName(MainWidget); + } // setupUi + + void retranslateUi(QWidget* MainWidget) + { + MainWidget->setWindowTitle(QCoreApplication::translate("MainWidget", "MainWidget", nullptr)); + } // retranslateUi +}; + +namespace Ui { +class MainWidget : public Ui_MainWidget { +}; +} // namespace Ui + +QT_END_NAMESPACE + +#endif // UI_MAINWIDGET_H diff --git a/ui.gni b/ui.gni new file mode 100644 index 0000000..baf26af --- /dev/null +++ b/ui.gni @@ -0,0 +1,101 @@ +# Copyright (c) 2020-2021 Huawei Device Co., Ltd. +# 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. + +GRAPHIC_UI_PATH = "//foundation/graphic/ui" + +graphic_ui_include_dirs = [ + "$GRAPHIC_UI_PATH/interfaces/kits", + "$GRAPHIC_UI_PATH/interfaces/innerkits", +] + +graphic_ui_sources = [ + "$GRAPHIC_UI_PATH/frameworks/animator/animator.cpp", + "$GRAPHIC_UI_PATH/frameworks/animator/easing_equation.cpp", + "$GRAPHIC_UI_PATH/frameworks/animator/interpolation.cpp", + "$GRAPHIC_UI_PATH/frameworks/common/graphic_startup.cpp", + "$GRAPHIC_UI_PATH/frameworks/common/image.cpp", + "$GRAPHIC_UI_PATH/frameworks/common/input_device_manager.cpp", + "$GRAPHIC_UI_PATH/frameworks/common/screen.cpp", + "$GRAPHIC_UI_PATH/frameworks/common/screen_device_proxy.cpp", + "$GRAPHIC_UI_PATH/frameworks/common/task.cpp", + "$GRAPHIC_UI_PATH/frameworks/common/text.cpp", + "$GRAPHIC_UI_PATH/frameworks/common/typed_text.cpp", + "$GRAPHIC_UI_PATH/frameworks/components/root_view.cpp", + "$GRAPHIC_UI_PATH/frameworks/components/text_adapter.cpp", + "$GRAPHIC_UI_PATH/frameworks/components/ui_abstract_clock.cpp", + "$GRAPHIC_UI_PATH/frameworks/components/ui_abstract_progress.cpp", + "$GRAPHIC_UI_PATH/frameworks/components/ui_abstract_scroll.cpp", + "$GRAPHIC_UI_PATH/frameworks/components/ui_analog_clock.cpp", + "$GRAPHIC_UI_PATH/frameworks/components/ui_arc_label.cpp", + "$GRAPHIC_UI_PATH/frameworks/components/ui_axis.cpp", + "$GRAPHIC_UI_PATH/frameworks/components/ui_box_progress.cpp", + "$GRAPHIC_UI_PATH/frameworks/components/ui_button.cpp", + "$GRAPHIC_UI_PATH/frameworks/components/ui_canvas.cpp", + "$GRAPHIC_UI_PATH/frameworks/components/ui_chart.cpp", + "$GRAPHIC_UI_PATH/frameworks/components/ui_checkbox.cpp", + "$GRAPHIC_UI_PATH/frameworks/components/ui_circle_progress.cpp", + "$GRAPHIC_UI_PATH/frameworks/components/ui_dialog.cpp", + "$GRAPHIC_UI_PATH/frameworks/components/ui_digital_clock.cpp", + "$GRAPHIC_UI_PATH/frameworks/components/ui_image_animator.cpp", + "$GRAPHIC_UI_PATH/frameworks/components/ui_image_view.cpp", + "$GRAPHIC_UI_PATH/frameworks/components/ui_label.cpp", + "$GRAPHIC_UI_PATH/frameworks/components/ui_label_button.cpp", + "$GRAPHIC_UI_PATH/frameworks/components/ui_list.cpp", + "$GRAPHIC_UI_PATH/frameworks/components/ui_picker.cpp", + "$GRAPHIC_UI_PATH/frameworks/components/ui_qrcode.cpp", + "$GRAPHIC_UI_PATH/frameworks/components/ui_radio_button.cpp", + "$GRAPHIC_UI_PATH/frameworks/components/ui_repeat_button.cpp", + "$GRAPHIC_UI_PATH/frameworks/components/ui_scroll_view.cpp", + "$GRAPHIC_UI_PATH/frameworks/components/ui_slider.cpp", + "$GRAPHIC_UI_PATH/frameworks/components/ui_surface_view.cpp", + "$GRAPHIC_UI_PATH/frameworks/components/ui_swipe_view.cpp", + "$GRAPHIC_UI_PATH/frameworks/components/ui_texture_mapper.cpp", + "$GRAPHIC_UI_PATH/frameworks/components/ui_time_picker.cpp", + "$GRAPHIC_UI_PATH/frameworks/components/ui_toggle_button.cpp", + "$GRAPHIC_UI_PATH/frameworks/components/ui_view.cpp", + "$GRAPHIC_UI_PATH/frameworks/components/ui_view_group.cpp", + "$GRAPHIC_UI_PATH/frameworks/core/render_manager.cpp", + "$GRAPHIC_UI_PATH/frameworks/core/task_manager.cpp", + "$GRAPHIC_UI_PATH/frameworks/default_resource/check_box_res.cpp", + "$GRAPHIC_UI_PATH/frameworks/dfx/event_injector.cpp", + "$GRAPHIC_UI_PATH/frameworks/dfx/key_event_injector.cpp", + "$GRAPHIC_UI_PATH/frameworks/dfx/point_event_injector.cpp", + "$GRAPHIC_UI_PATH/frameworks/dfx/ui_dump_dom_tree.cpp", + "$GRAPHIC_UI_PATH/frameworks/dock/input_device.cpp", + "$GRAPHIC_UI_PATH/frameworks/dock/key_input_device.cpp", + "$GRAPHIC_UI_PATH/frameworks/dock/pointer_input_device.cpp", + "$GRAPHIC_UI_PATH/frameworks/dock/virtual_input_device.cpp", + "$GRAPHIC_UI_PATH/frameworks/draw/draw_arc.cpp", + "$GRAPHIC_UI_PATH/frameworks/draw/draw_curve.cpp", + "$GRAPHIC_UI_PATH/frameworks/draw/draw_image.cpp", + "$GRAPHIC_UI_PATH/frameworks/draw/draw_label.cpp", + "$GRAPHIC_UI_PATH/frameworks/draw/draw_line.cpp", + "$GRAPHIC_UI_PATH/frameworks/draw/draw_rect.cpp", + "$GRAPHIC_UI_PATH/frameworks/draw/draw_triangle.cpp", + "$GRAPHIC_UI_PATH/frameworks/draw/draw_utils.cpp", + "$GRAPHIC_UI_PATH/frameworks/events/event.cpp", + "$GRAPHIC_UI_PATH/frameworks/font/base_font.cpp", + "$GRAPHIC_UI_PATH/frameworks/font/glyphs_manager.cpp", + "$GRAPHIC_UI_PATH/frameworks/font/ui_font.cpp", + "$GRAPHIC_UI_PATH/frameworks/font/ui_font_adaptor.cpp", + "$GRAPHIC_UI_PATH/frameworks/font/ui_font_allocator.cpp", + "$GRAPHIC_UI_PATH/frameworks/font/ui_font_cache.cpp", + "$GRAPHIC_UI_PATH/frameworks/font/ui_font_vector.cpp", + "$GRAPHIC_UI_PATH/frameworks/font/ui_multi_font_manager.cpp", + "$GRAPHIC_UI_PATH/frameworks/imgdecode/cache_manager.cpp", + "$GRAPHIC_UI_PATH/frameworks/imgdecode/file_img_decoder.cpp", + "$GRAPHIC_UI_PATH/frameworks/imgdecode/image_load.cpp", + "$GRAPHIC_UI_PATH/frameworks/layout/flex_layout.cpp", + "$GRAPHIC_UI_PATH/frameworks/layout/grid_layout.cpp", + "$GRAPHIC_UI_PATH/frameworks/layout/list_layout.cpp", + "$GRAPHIC_UI_PATH/frameworks/themes/theme.cpp", + "$GRAPHIC_UI_PATH/frameworks/themes/theme_manager.cpp", +]