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 "ui_test_focus_manager.h"
17 
18 #if ENABLE_FOCUS_MANAGER
19 namespace OHOS {
20 namespace {
21 const uint16_t LABEL_BUTTON_DEFAULT_FONT_SIZE = 15;
22 const uint16_t LABEL_BUTTON_DEFAULT_WIDTH = 60;
23 const uint16_t LABEL_BUTTON_DEFAULT_HEIGHT = 40;
24 } // namespace
25 
26 class TestOnFocusListener : public UIView::OnFocusListener {
27 public:
TestOnFocusListener()28     TestOnFocusListener() {}
29 
~TestOnFocusListener()30     ~TestOnFocusListener() {}
31 
OnFocus(UIView & view)32     bool OnFocus(UIView& view) override
33     {
34         if (view.IsViewGroup()) {
35             view.SetStyle(STYLE_BORDER_COLOR, Color::Red().full);
36         } else {
37             view.SetStyle(STYLE_BACKGROUND_COLOR, Color::Red().full);
38         }
39         view.Invalidate();
40         return true;
41     }
42 
OnBlur(UIView & view)43     bool OnBlur(UIView& view) override
44     {
45         if (view.IsViewGroup()) {
46             view.SetStyle(STYLE_BORDER_COLOR, Color::White().full);
47         } else {
48             /* 0: red, 125: green, 255: blue */
49             view.SetStyle(STYLE_BACKGROUND_COLOR, Color::GetColorFromRGB(0, 125, 255).full);
50         }
51         view.Invalidate();
52         return true;
53     }
54 };
55 
56 class RequestFocusByDirectionOnClickListener : public UIView::OnClickListener {
57 public:
RequestFocusByDirectionOnClickListener(uint8_t direction)58     explicit RequestFocusByDirectionOnClickListener(uint8_t direction) : direction_(direction) {}
59 
~RequestFocusByDirectionOnClickListener()60     ~RequestFocusByDirectionOnClickListener() {}
61 
OnClick(UIView & view,const ClickEvent & event)62     bool OnClick(UIView& view, const ClickEvent& event)
63     {
64         FocusManager::GetInstance()->RequestFocusByDirection(direction_);
65         return true;
66     }
67 private:
68     uint8_t direction_ = 0;
69 };
70 
71 class ResetFocusOnClickListener : public UIView::OnClickListener {
72 public:
ResetFocusOnClickListener(UIView * focus)73     explicit ResetFocusOnClickListener(UIView* focus) : focus_(focus) {}
74 
~ResetFocusOnClickListener()75     ~ResetFocusOnClickListener() {}
76 
OnClick(UIView & view,const ClickEvent & event)77     bool OnClick(UIView& view, const ClickEvent& event)
78     {
79         FocusManager::GetInstance()->RequestFocus(focus_);
80         return true;
81     }
82 
83 private:
84     UIView* focus_ = nullptr;
85 };
86 
87 class SetGroupInterceptOnClickListener : public UIView::OnClickListener {
88 public:
SetGroupInterceptOnClickListener(UIViewGroup * viewGroup,bool intercept)89     SetGroupInterceptOnClickListener(UIViewGroup* viewGroup, bool intercept)
90         : viewGroup_(viewGroup), intercept_(intercept) {}
91 
~SetGroupInterceptOnClickListener()92     ~SetGroupInterceptOnClickListener() {}
93 
OnClick(UIView & view,const ClickEvent & event)94     bool OnClick(UIView& view, const ClickEvent& event)
95     {
96         if (viewGroup_ != nullptr) {
97             viewGroup_->SetInterceptFocus(intercept_);
98             return true;
99         }
100         return false;
101     }
102 private:
103     UIViewGroup* viewGroup_ = nullptr;
104     bool intercept_;
105 };
106 
107 class SetGroupInterceptFalseOnClickListener : public UIView::OnClickListener {
108 public:
SetGroupInterceptFalseOnClickListener(UIViewGroup * viewGroup)109     explicit SetGroupInterceptFalseOnClickListener(UIViewGroup* viewGroup) : viewGroup_(viewGroup) {}
110 
~SetGroupInterceptFalseOnClickListener()111     ~SetGroupInterceptFalseOnClickListener() {}
112 
OnClick(UIView & view,const ClickEvent & event)113     bool OnClick(UIView& view, const ClickEvent& event)
114     {
115         viewGroup_->SetInterceptFocus(false);
116         return true;
117     }
118 private:
119     UIViewGroup* viewGroup_ = nullptr;
120 };
121 
122 class SetFocusableOnClickListener : public UIView::OnClickListener {
123 public:
SetFocusableOnClickListener(UIView * view,bool enable)124     SetFocusableOnClickListener(UIView* view, bool enable) : view_(view), enable_(enable) {}
125 
~SetFocusableOnClickListener()126     ~SetFocusableOnClickListener() {}
127 
OnClick(UIView & view,const ClickEvent & event)128     bool OnClick(UIView& view, const ClickEvent& event)
129     {
130         view_->SetFocusable(enable_);
131         return true;
132     }
133 private:
134     UIView* view_ = nullptr;
135     bool enable_ = false;
136 };
137 
138 class RequestFocusOnClickListener : public UIView::OnClickListener {
139 public:
RequestFocusOnClickListener(UIView * view)140     explicit RequestFocusOnClickListener(UIView* view) : view_(view) {}
141 
~RequestFocusOnClickListener()142     ~RequestFocusOnClickListener() {}
143 
OnClick(UIView & view,const ClickEvent & event)144     bool OnClick(UIView& view, const ClickEvent& event)
145     {
146         FocusManager::GetInstance()->RequestFocus(view_);
147         return true;
148     }
149 private:
150     UIView* view_ = nullptr;
151 };
152 
153 class ClearFocusOnClickListener : public UIView::OnClickListener {
154 public:
ClearFocusOnClickListener()155     ClearFocusOnClickListener() {}
156 
~ClearFocusOnClickListener()157     ~ClearFocusOnClickListener() {}
158 
OnClick(UIView & view,const ClickEvent & event)159     bool OnClick(UIView& view, const ClickEvent& event)
160     {
161         FocusManager::GetInstance()->ClearFocus();
162         return true;
163     }
164 };
165 
SetUp()166 void UITestFocusManager::SetUp()
167 {
168     if (container_ == nullptr) {
169         container_ = new UIScrollView();
170         container_->Resize(Screen::GetInstance().GetWidth(), Screen::GetInstance().GetHeight() - BACK_BUTTON_HEIGHT);
171         container_->SetHorizontalScrollState(false);
172     }
173 }
174 
TearDown()175 void UITestFocusManager::TearDown()
176 {
177     FocusManager::GetInstance()->ClearFocus();
178     TearDownListeners001();
179     if (setFocusableViewListener_ != nullptr) {
180         delete setFocusableViewListener_;
181         setFocusableViewListener_ = nullptr;
182     }
183     if (setFocusableViewListener1_ != nullptr) {
184         delete setFocusableViewListener1_;
185         setFocusableViewListener1_ = nullptr;
186     }
187     if (setGroupInterceptListener_ != nullptr) {
188         delete setGroupInterceptListener_;
189         setGroupInterceptListener_ = nullptr;
190     }
191     if (setGroupInterceptListener1_ != nullptr) {
192         delete setGroupInterceptListener1_;
193         setGroupInterceptListener1_ = nullptr;
194     }
195     if (resetFocusListener_ != nullptr) {
196         delete resetFocusListener_;
197         resetFocusListener_ = nullptr;
198     }
199     if (clearFocusListener_ != nullptr) {
200         delete clearFocusListener_;
201         clearFocusListener_ = nullptr;
202     }
203     DeleteChildren(container_);
204     container_ = nullptr;
205 }
206 
TearDownListeners001()207 void UITestFocusManager::TearDownListeners001()
208 {
209     if (testOnFocusListener_ != nullptr) {
210         delete testOnFocusListener_;
211         testOnFocusListener_ = nullptr;
212     }
213     if (requestFocusByDirectionLeftListener_ != nullptr) {
214         delete requestFocusByDirectionLeftListener_;
215         requestFocusByDirectionLeftListener_ = nullptr;
216     }
217     if (requestFocusByDirectionRightListener_ != nullptr) {
218         delete requestFocusByDirectionRightListener_;
219         requestFocusByDirectionRightListener_ = nullptr;
220     }
221     if (requestFocusByDirectionUpListener_ != nullptr) {
222         delete requestFocusByDirectionUpListener_;
223         requestFocusByDirectionUpListener_ = nullptr;
224     }
225     if (requestFocusByDirectionLeftListener_ != nullptr) {
226         delete requestFocusByDirectionLeftListener_;
227         requestFocusByDirectionLeftListener_ = nullptr;
228     }
229     if (requestFocusByDirectionDownListener_ != nullptr) {
230         delete requestFocusByDirectionDownListener_;
231         requestFocusByDirectionDownListener_ = nullptr;
232     }
233 }
234 
GetTestView()235 const UIView* UITestFocusManager::GetTestView()
236 {
237     UIKitFocusManagerTest001();
238     return container_;
239 }
240 
CreateTestUILabel(UIViewGroup * parent,int16_t x,int16_t y,const char * text,bool focusable)241 UIView* UITestFocusManager::CreateTestUILabel(UIViewGroup* parent, int16_t x, int16_t y,
242     const char* text, bool focusable)
243 {
244     UILabel* label = new UILabel();
245     parent->Add(label);
246     label->SetPosition(x, y, LABEL_BUTTON_DEFAULT_WIDTH, LABEL_BUTTON_DEFAULT_HEIGHT);
247     label->SetText(text);
248     label->SetViewId(text);
249     label->SetFont(DEFAULT_VECTOR_FONT_FILENAME, LABEL_BUTTON_DEFAULT_FONT_SIZE);
250     label->SetFocusable(focusable);
251     /* 0: red, 125: green, 255: blue */
252     label->SetStyle(STYLE_BACKGROUND_COLOR, Color::GetColorFromRGB(0, 125, 255).full);
253     label->SetStyle(STYLE_BACKGROUND_OPA, OPA_OPAQUE);
254     label->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER);
255     if (testOnFocusListener_ == nullptr) {
256         testOnFocusListener_ = static_cast<UIView::OnFocusListener*>(new TestOnFocusListener());
257     }
258     label->SetOnFocusListener(testOnFocusListener_);
259     return label;
260 }
261 
CreateTestUIViewGroup(UIViewGroup * parent,bool focusable,bool interceptFocus)262 UIViewGroup* UITestFocusManager::CreateTestUIViewGroup(UIViewGroup* parent, bool focusable, bool interceptFocus)
263 {
264     UIViewGroup* viewGroup = new UIViewGroup();
265     parent->Add(viewGroup);
266     viewGroup->SetFocusable(focusable);
267     viewGroup->SetInterceptFocus(interceptFocus);
268     viewGroup->SetStyle(STYLE_BORDER_COLOR, Color::White().full);
269     viewGroup->SetStyle(STYLE_BORDER_OPA, HALF_OPA_OPAQUE);
270     viewGroup->SetStyle(STYLE_BORDER_WIDTH, 1);
271     viewGroup->SetStyle(STYLE_BORDER_RADIUS, VIEW_STYLE_BORDER_RADIUS);
272     if (testOnFocusListener_ == nullptr) {
273         testOnFocusListener_ = static_cast<UIView::OnFocusListener*>(new TestOnFocusListener());
274     }
275     viewGroup->SetOnFocusListener(testOnFocusListener_);
276     return viewGroup;
277 }
278 
UIKitFocusManagerTest001()279 void UITestFocusManager::UIKitFocusManagerTest001()
280 {
281     UIViewGroup* viewGroup = CreateTestUIViewGroup(container_, true, false);
282     /* 600: width, 350: height */
283     viewGroup->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE2, VIEW_DISTANCE_TO_TOP_SIDE, 600, 350);
284     UIViewGroup* viewGroup1 = CreateTestUIViewGroup(viewGroup, true, false);
285 
286     CreateLabels(viewGroup, viewGroup1);
287 
288     UIViewGroup* btnViewGroup = new UIViewGroup();
289     /* 650: x, 300: width, 400: height */
290     btnViewGroup->SetPosition(650, VIEW_DISTANCE_TO_TOP_SIDE, 300, 400);
291     container_->Add(btnViewGroup);
292 
293     /* 10: x, 10: y */
294     SetUpButton("向左 ", 10, 10, btnViewGroup, requestFocusByDirectionLeftListener_, UI_TEST_TOWRADS_LEFT);
295     /* 150: x, 10: y */
296     SetUpButton("向右 ", 150, 10, btnViewGroup, requestFocusByDirectionRightListener_, UI_TEST_TOWRADS_RIGHT);
297     /* 10: x, 60: y */
298     SetUpButton("向上 ", 10, 60, btnViewGroup, requestFocusByDirectionUpListener_, UI_TEST_TOWRADS_UP);
299     /* 150: x, 60: y */
300     SetUpButton("向下 ", 150, 60, btnViewGroup, requestFocusByDirectionDownListener_, UI_TEST_TOWRADS_DOWN);
301     /* 10: x, 110: y */
302     SetUpButton("2可获焦 ", 10, 110, btnViewGroup, setFocusableViewListener_, UI_TEST_2_FOCUSABLE);
303     /* 150: x, 110: y */
304     SetUpButton("2不可获焦 ", 150, 110, btnViewGroup, setFocusableViewListener1_, UI_TEST_2_UNFOCUSABLE);
305     /* 10: x, 160: y */
306     SetUpButton("设置4容器拦截 ", 10, 160, btnViewGroup, setGroupInterceptListener_, UI_TEST_4_INTERCEPT);
307     /* 150: x, 160: y */
308     SetUpButton("取消4容器拦截 ", 150, 160, btnViewGroup, setGroupInterceptListener1_, UI_TEST_4_CANCEL_INTERCEPT);
309     /* 10: x, 210: y */
310     SetUpButton("重置焦点 ", 10, 210, btnViewGroup, resetFocusListener_, UI_TEST_RESET_FOCUS);
311     /* 150: x, 210: y */
312     SetUpButton("清除焦点 ", 150, 210, btnViewGroup, clearFocusListener_, UI_TEST_CLEAR_FOCUS);
313 
314     FocusManager::GetInstance()->RequestFocus(viewGroup1->GetChildById("1"));
315 }
316 
CreateLabels(UIViewGroup * viewGroup,UIViewGroup * viewGroup1)317 void UITestFocusManager::CreateLabels(UIViewGroup* viewGroup, UIViewGroup* viewGroup1)
318 {
319     UILabel* label = new UILabel();
320     container_->Add(label);
321     /* 288: width */
322     label->SetPosition(TEXT_DISTANCE_TO_LEFT_SIDE, TEXT_DISTANCE_TO_TOP_SIDE, 288, TITLE_LABEL_DEFAULT_HEIGHT);
323     label->SetText("焦点管理效果 ");
324     label->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE);
325 
326     UIViewGroup* viewGroup2 = CreateTestUIViewGroup(viewGroup1, true, false);
327     UIViewGroup* viewGroup3 = CreateTestUIViewGroup(viewGroup, true, false);
328     UIViewGroup* viewGroup4 = CreateTestUIViewGroup(viewGroup3, true, false);
329     UIViewGroup* viewGroup5 = CreateTestUIViewGroup(viewGroup4, true, false);
330     UIViewGroup* viewGroup6 = CreateTestUIViewGroup(viewGroup, true, false);
331 
332     viewGroup1->SetPosition(5, 5, 270, 60);      /* 5: x,   5: y;   270: width, 60: height */
333     viewGroup2->SetPosition(100, 5, 80, 50);     /* 100: x, 5: y;   80: width,  50: height */
334     viewGroup3->SetPosition(290, 5, 280, 115);   /* 290: x, 5: y;   280: width, 115: height */
335     viewGroup4->SetPosition(5, 5, 260, 60);      /* 5: x,   5: y;   260: width, 60: height */
336     viewGroup5->SetPosition(5, 5, 250, 50);      /* 5: x,   5: y;   250: width, 50: height */
337     viewGroup6->SetPosition(100, 160, 400, 160); /* 100: x, 160: y; 400: width, 160: height */
338 
339     CreateTestUILabel(viewGroup1, 0, 5, "1", true);                   /* 0: x,   5: y */
340     UIView* view2 = CreateTestUILabel(viewGroup1, 195, 5, "2", true); /* 195: x, 5: y */
341     CreateTestUILabel(viewGroup2, 5, 5, "3", true);                   /* 5: x,   5: y */
342     CreateTestUILabel(viewGroup5, 5, 5, "4", true);                   /* 5: x,   5: y */
343     CreateTestUILabel(viewGroup5, 180, 5, "5", true);                 /* 180: x, 5: y */
344     CreateTestUILabel(viewGroup3, 150, 70, "6", true);                /* 150: x, 70: y */
345 
346     CreateTestUILabel(viewGroup, 80, 100, "7", true);                 /* 80: x,  100: y */
347     CreateTestUILabel(viewGroup6, 5, 5, "8", true);                   /* 5: x,   5: y */
348     CreateTestUILabel(viewGroup6, 100, 80, "9", true);                /* 100: x, 80: y */
349     CreateTestUILabel(viewGroup6, 300, 5, "10", true);                /* 300: x, 5: y */
350 
351     InitListeners(viewGroup1, viewGroup5, view2);
352 }
353 
InitListeners(UIViewGroup * viewGroup1,UIViewGroup * viewGroup5,UIView * view2)354 void UITestFocusManager::InitListeners(UIViewGroup* viewGroup1, UIViewGroup* viewGroup5, UIView* view2)
355 {
356     if (requestFocusByDirectionLeftListener_ == nullptr) {
357         requestFocusByDirectionLeftListener_ = static_cast<UIView::OnClickListener*>(
358             new RequestFocusByDirectionOnClickListener(FOCUS_DIRECTION_LEFT));
359     }
360     if (requestFocusByDirectionRightListener_ == nullptr) {
361         requestFocusByDirectionRightListener_ = static_cast<UIView::OnClickListener*>(
362             new RequestFocusByDirectionOnClickListener(FOCUS_DIRECTION_RIGHT));
363     }
364     if (requestFocusByDirectionUpListener_ == nullptr) {
365         requestFocusByDirectionUpListener_ = static_cast<UIView::OnClickListener*>(
366             new RequestFocusByDirectionOnClickListener(FOCUS_DIRECTION_UP));
367     }
368     if (requestFocusByDirectionDownListener_ == nullptr) {
369         requestFocusByDirectionDownListener_ = static_cast<UIView::OnClickListener*>(
370             new RequestFocusByDirectionOnClickListener(FOCUS_DIRECTION_DOWN));
371     }
372     if (setFocusableViewListener_ == nullptr) {
373         setFocusableViewListener_ = static_cast<UIView::OnClickListener*>(
374             new SetFocusableOnClickListener(view2, true));
375     }
376     if (setFocusableViewListener1_ == nullptr) {
377         setFocusableViewListener1_ = static_cast<UIView::OnClickListener*>(
378             new SetFocusableOnClickListener(view2, false));
379     }
380     if (setGroupInterceptListener_ == nullptr) {
381         setGroupInterceptListener_ = static_cast<UIView::OnClickListener*>(
382             new SetGroupInterceptOnClickListener(viewGroup5, true));
383     }
384     if (setGroupInterceptListener1_ == nullptr) {
385         setGroupInterceptListener1_ = static_cast<UIView::OnClickListener*>(
386             new SetGroupInterceptOnClickListener(viewGroup5, false));
387     }
388     if (resetFocusListener_ == nullptr) {
389         resetFocusListener_ = static_cast<UIView::OnClickListener*>(
390             new ResetFocusOnClickListener(viewGroup1->GetChildById("1")));
391     }
392     if (clearFocusListener_ == nullptr) {
393         clearFocusListener_ = static_cast<UIView::OnClickListener*>(new ClearFocusOnClickListener());
394     }
395 }
396 
SetUpButton(const char * title,int16_t x,int16_t y,UIViewGroup * viewGroup,UIView::OnClickListener * listener,const char * id)397 UILabelButton* UITestFocusManager::SetUpButton(const char* title, int16_t x, int16_t y, UIViewGroup* viewGroup,
398     UIView::OnClickListener* listener, const char* id)
399 {
400     if (viewGroup == nullptr || title == nullptr || id == nullptr) {
401         return nullptr;
402     }
403 
404     UILabelButton* btn = new UILabelButton();
405     btn->SetPosition(x, y, BUTTON_WIDHT2, BUTTON_HEIGHT1);
406     btn->SetText(title);
407     btn->SetFont(DEFAULT_VECTOR_FONT_FILENAME, BUTTON_LABEL_SIZE);
408     btn->SetOnClickListener(listener);
409     btn->SetStyleForState(STYLE_BORDER_RADIUS, BUTTON_STYLE_BORDER_RADIUS_VALUE, UIButton::RELEASED);
410     btn->SetStyleForState(STYLE_BORDER_RADIUS, BUTTON_STYLE_BORDER_RADIUS_VALUE, UIButton::PRESSED);
411     btn->SetStyleForState(STYLE_BORDER_RADIUS, BUTTON_STYLE_BORDER_RADIUS_VALUE, UIButton::INACTIVE);
412     btn->SetStyleForState(STYLE_BACKGROUND_COLOR, BUTTON_STYLE_BACKGROUND_COLOR_VALUE, UIButton::RELEASED);
413     btn->SetStyleForState(STYLE_BACKGROUND_COLOR, BUTTON_STYLE_BACKGROUND_COLOR_VALUE, UIButton::PRESSED);
414     btn->SetStyleForState(STYLE_BACKGROUND_COLOR, BUTTON_STYLE_BACKGROUND_COLOR_VALUE, UIButton::INACTIVE);
415     btn->SetViewId(id);
416     viewGroup->Add(btn);
417     return btn;
418 }
419 } // namespace OHOS
420 #endif
421