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 
36 namespace OHOS {
37 namespace {
38 const uint16_t MAX_LIST_NUM = 40;
39 }
40 static RootView* g_rootView1 = nullptr;
41 static RootView* g_rootView2 = nullptr;
42 static RootView* g_rootView3 = nullptr;
43 static bool g_flag = true;
44 
CreateDefaultWindow(RootView * rootView,int x,int y)45 void 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 
61 class ImageAnimatorCallbackDemo : public AnimatorCallback {
62 public:
ImageAnimatorCallbackDemo()63     ImageAnimatorCallbackDemo() : times_(0) {}
~ImageAnimatorCallbackDemo()64     virtual ~ImageAnimatorCallbackDemo() {}
65 
66     enum {
67         CONDITION0,
68         CONDITION1,
69         CONDITION2,
70         CONDITION3,
71         CONDITION4,
72         CONDITION5,
73         CONDITION_COUNT,
74     };
75 
Callback(UIView * view)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 
130 protected:
131     int16_t times_;
132 };
133 
AddButton()134 void 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 
AddBlock()153 void 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 
TestWindow()188 void 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 
235 RootView* g_rootViewList[MAX_LIST_NUM];
TestWindowNumLimit()236 void 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 
258 static uint32_t g_fontMemBaseAddr[MIN_FONT_PSRAM_LENGTH / 4];
259 #if ENABLE_ICU
260 static uint8_t g_icuMemBaseAddr[OHOS::SHAPING_WORD_DICT_LENGTH];
261 #endif
InitFontEngine()262 static 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 
main(int argc,char * argv[])281 int 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