1/*
2 * Copyright (c) 2020-2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#include "animator/animator.h"
17#include "common/graphic_startup.h"
18#include "common/task_manager.h"
19#include "components/root_view.h"
20#include "components/ui_button.h"
21#include "components/ui_image_view.h"
22#include "components/ui_label.h"
23#include "font/ui_font.h"
24#if ENABLE_VECTOR_FONT
25#include "font/ui_font_vector.h"
26#else
27#include "common/ui_text_language.h"
28#include "font/ui_font_bitmap.h"
29#endif
30#include "gfx_utils/graphic_log.h"
31#include "graphic_config.h"
32#include "window/window.h"
33
34#include <unistd.h>
35
36namespace OHOS {
37namespace {
38const uint16_t MAX_LIST_NUM = 40;
39}
40static RootView* g_rootView1 = nullptr;
41static RootView* g_rootView2 = nullptr;
42static RootView* g_rootView3 = nullptr;
43static bool g_flag = true;
44
45void CreateDefaultWindow(RootView* rootView, int x, int y)
46{
47    if (rootView != nullptr) {
48        WindowConfig config = {};
49        config.rect = rootView->GetRect();
50        config.rect.SetPosition(x, y);
51        Window* window = Window::CreateWindow(config);
52        if (window != nullptr) {
53            window->BindRootView(rootView);
54            window->Show();
55        } else {
56            GRAPHIC_LOGE("Create window false!");
57        }
58    }
59}
60
61class ImageAnimatorCallbackDemo : public AnimatorCallback {
62public:
63    ImageAnimatorCallbackDemo() : times_(0) {}
64    virtual ~ImageAnimatorCallbackDemo() {}
65
66    enum {
67        CONDITION0,
68        CONDITION1,
69        CONDITION2,
70        CONDITION3,
71        CONDITION4,
72        CONDITION5,
73        CONDITION_COUNT,
74    };
75
76    virtual void Callback(UIView* view)
77    {
78        static int i = 0;
79        if ((times_++ % 90) != 0) { // 90: animator callback is performed every 90 ticks
80            return;
81        }
82        switch ((++i) % CONDITION_COUNT) {
83            case CONDITION0: {
84                if (g_flag) {
85                    g_rootView3->GetBoundWindow()->LowerToBottom();
86                } else {
87                    g_rootView3->GetBoundWindow()->RaiseToTop();
88                }
89                g_flag = !g_flag;
90                break;
91            }
92            case CONDITION1: {
93                if (g_flag) {
94                    g_rootView1->Resize(403, 201);                   // 403: width, 201: height
95                    g_rootView1->GetBoundWindow()->Resize(403, 201); // 403: width, 201: height
96                } else {
97                    g_rootView1->Resize(600, 300);                   // 600: width, 300: height
98                    g_rootView1->GetBoundWindow()->Resize(600, 300); // 600: width, 300: height
99                }
100                break;
101            }
102            case CONDITION2: {
103                Window* window = g_rootView3->GetBoundWindow();
104                int x = (window->GetRect().GetX() + 40) % 400; // 40: x offset, 400: maximum value of x
105                window->MoveTo(x, window->GetRect().GetY());
106                break;
107            }
108            case CONDITION3: {
109                Window* window = g_rootView2->GetBoundWindow();
110                if (window != nullptr) {
111                    Window::DestroyWindow(window);
112                } else {
113                    g_rootView2->Invalidate();
114                    CreateDefaultWindow(g_rootView2, 70, 75); // 70: x, 75: y
115                }
116                break;
117            }
118            case CONDITION4: {
119                g_rootView3->GetBoundWindow()->Hide();
120                break;
121            }
122            case CONDITION5: {
123                g_rootView3->GetBoundWindow()->Show();
124            }
125            default:
126                break;
127        }
128    }
129
130protected:
131    int16_t times_;
132};
133
134void AddButton()
135{
136    UIButton* button = new UIButton();
137    button->SetPosition(40, 40); // 40: x, 40: y
138    button->SetWidth(40);        // 40: width
139    button->SetHeight(40);       // 40: height
140    button->SetStyle(STYLE_BACKGROUND_COLOR, Color::Gray().full);
141
142    UIButton* button1 = new UIButton();
143    button1->SetPosition(30, 10); // 30: x, 10: y
144    button1->SetWidth(60);        // 60: width
145    button1->SetHeight(60);       // 60: height
146    button1->SetStyle(STYLE_BACKGROUND_COLOR, Color::Green().full);
147    button1->SetStyle(STYLE_BACKGROUND_OPA, 200); // 200: background opacity
148    button1->SetStyle(STYLE_BORDER_RADIUS, 3);    // 3: border radius
149    g_rootView1->Add(button1);
150    g_rootView2->Add(button);
151}
152
153void AddBlock()
154{
155    UIViewGroup* block = new UIViewGroup();
156    block->SetPosition(100, 40); // 100: x, 40: y
157    block->SetWidth(60);         // 60: width
158    block->SetHeight(60);        // 60: height
159    block->SetStyle(STYLE_BACKGROUND_COLOR, Color::Gray().full);
160    block->SetStyle(STYLE_BACKGROUND_OPA, 200); // 200: background opacity
161
162    UIViewGroup* block2 = new UIViewGroup();
163    block2->SetPosition(40, 40); // 40: x, 40: y
164    block2->SetWidth(60);        // 60: width
165    block2->SetHeight(60);       // 60: height
166    block2->SetStyle(STYLE_BACKGROUND_COLOR, Color::Yellow().full);
167    block2->SetStyle(STYLE_BACKGROUND_OPA, OPA_OPAQUE);
168
169    UIViewGroup* block3 = new UIViewGroup();
170    block3->SetPosition(100, 40); // 100: x, 40: y
171    block3->SetWidth(60);         // 60: width
172    block3->SetHeight(60);        // 60: height
173    block3->SetStyle(STYLE_BACKGROUND_COLOR, Color::Yellow().full);
174    block3->SetStyle(STYLE_BACKGROUND_OPA, 200); // 200: background opacity
175
176    UIViewGroup* block4 = new UIViewGroup();
177    block4->SetPosition(1, 1);
178    block4->SetWidth(10);  // 10: width
179    block4->SetHeight(10); // 10: height
180    block4->SetStyle(STYLE_BACKGROUND_COLOR, Color::Red().full);
181    block4->SetStyle(STYLE_BACKGROUND_OPA, OPA_OPAQUE);
182    g_rootView1->Add(block4);
183    g_rootView2->Add(block);
184    g_rootView3->Add(block2);
185    g_rootView3->Add(block3);
186}
187
188void TestWindow()
189{
190    g_rootView1 = RootView::GetWindowRootView();
191    g_rootView1->SetWidth(600);  // 600: width
192    g_rootView1->SetHeight(300); // 300: height
193    g_rootView1->SetPosition(0, 0);
194    g_rootView1->SetStyle(STYLE_BACKGROUND_COLOR, Color::Olive().full);
195
196    g_rootView2 = RootView::GetWindowRootView();
197    g_rootView2->SetPosition(0, 0, 200, 200); // 200: width, 200: height
198    g_rootView2->SetStyle(STYLE_BACKGROUND_COLOR, Color::Yellow().full);
199
200    g_rootView3 = RootView::GetWindowRootView();
201    g_rootView3->SetPosition(0, 0, 200, 200); // 200: width, 200: height
202    g_rootView3->SetStyle(STYLE_BACKGROUND_COLOR, Color::Red().full);
203    g_rootView3->SetStyle(STYLE_BACKGROUND_OPA, OPA_OPAQUE);
204
205    UILabel* label = new UILabel();
206    label->SetPosition(100, 0, 100, 100);  // 100: x, 100: width, 100: height
207    label->SetFont("HYQiHei-65S.otf", 14); // 14: font size
208    label->SetText("轻量鸿蒙GUI");
209    label->SetStyle(STYLE_TEXT_COLOR, Color::Black().full);
210    label->SetStyle(STYLE_BACKGROUND_COLOR, Color::Yellow().full);
211    label->SetStyle(STYLE_BACKGROUND_OPA, OPA_OPAQUE);
212
213    UIImageView* image = new UIImageView;
214    image->SetPosition(220, 0, 80, 80); // 220: x, 80: width, 80: height
215    image->SetSrc("/user/data/A021_028.bin");
216
217    AddButton();
218    g_rootView1->Add(label);
219    g_rootView1->Add(image);
220    AddBlock();
221
222    g_rootView1->Invalidate();
223    g_rootView2->Invalidate();
224    g_rootView3->Invalidate();
225
226    auto imageAnimCallback = new ImageAnimatorCallbackDemo();
227    Animator* imageAnimator = new Animator(imageAnimCallback, g_rootView1, 0, true);
228    imageAnimator->Start();
229
230    CreateDefaultWindow(g_rootView1, 0, 50);    // 50: y
231    CreateDefaultWindow(g_rootView2, 70, 75);   // 70: x, 75: y
232    CreateDefaultWindow(g_rootView3, 120, 200); // 120: x, 200: y
233}
234
235RootView* g_rootViewList[MAX_LIST_NUM];
236void TestWindowNumLimit()
237{
238    for (int i = 0; i < MAX_LIST_NUM; i++) {
239        GRAPHIC_LOGI("CreateDefaultWindow, i = %d", i);
240        if (i == 10) { // 10, 9: Delete the tenth window in the 11th loop.
241            Window* window = g_rootViewList[9]->GetBoundWindow();
242            Window::DestroyWindow(window);
243        } else if (i == 15) { // 15, 5: Delete the sixth window in the 16th loop.
244            Window* window = g_rootViewList[5]->GetBoundWindow();
245            Window::DestroyWindow(window);
246        }
247        RootView* rootView = RootView::GetWindowRootView();
248        g_rootViewList[i] = rootView;
249        rootView->SetWidth(10);  // 10: width
250        rootView->SetHeight(10); // 10: height
251        rootView->SetPosition(0, 0);
252        rootView->SetStyle(STYLE_BACKGROUND_COLOR, Color::Olive().full);
253        rootView->Invalidate();
254        CreateDefaultWindow(rootView, 20 * i, 0); // 20: offset
255    }
256}
257
258static uint32_t g_fontMemBaseAddr[MIN_FONT_PSRAM_LENGTH / 4];
259#if ENABLE_ICU
260static uint8_t g_icuMemBaseAddr[OHOS::SHAPING_WORD_DICT_LENGTH];
261#endif
262static void InitFontEngine()
263{
264#if ENABLE_VECTOR_FONT
265    GraphicStartUp::InitFontEngine(reinterpret_cast<uintptr_t>(g_fontMemBaseAddr), MIN_FONT_PSRAM_LENGTH,
266                                   VECTOR_FONT_DIR, DEFAULT_VECTOR_FONT_FILENAME);
267#else
268    BitmapFontInit();
269    const char* dPath = "/user/data/font.bin";
270    GraphicStartUp::InitFontEngine(reinterpret_cast<uintptr_t>(g_fontMemBaseAddr), MIN_FONT_PSRAM_LENGTH,
271                                   dPath, nullptr);
272#endif
273
274#if ENABLE_ICU
275    GraphicStartUp::InitLineBreakEngine(reinterpret_cast<uintptr_t>(g_icuMemBaseAddr), SHAPING_WORD_DICT_LENGTH,
276                                        VECTOR_FONT_DIR, DEFAULT_LINE_BREAK_RULE_FILENAME);
277#endif
278}
279} // namespace OHOS
280
281int main(int argc, char* argv[])
282{
283    OHOS::GraphicStartUp::Init();
284    OHOS::InitFontEngine();
285    OHOS::TestWindow();
286    while (1) {
287        /* Periodically call TaskHandler(). It could be done in a timer interrupt or an OS task too. */
288        OHOS::TaskManager::GetInstance()->TaskHandler();
289        usleep(1000 * 10); /* 1000 * 10: Just to let the system breathe */
290    }
291    return 0;
292}
293