提交 6320ae9a 编写于 作者: O openharmony_ci 提交者: Gitee

!19 焦点管理

Merge pull request !19 from YueBiang/master
......@@ -108,6 +108,7 @@ shared_library("ui") {
"frameworks/dfx/point_event_injector.cpp",
"frameworks/dfx/ui_dump_dom_tree.cpp",
"frameworks/dfx/ui_screenshot.cpp",
"frameworks/dock/focus_manager.cpp",
"frameworks/dock/input_device.cpp",
"frameworks/dock/key_input_device.cpp",
"frameworks/dock/ohos/ohos_input_device.cpp",
......
......@@ -33,6 +33,9 @@ UIAbstractScroll::UIAbstractScroll()
#if ENABLE_ROTATE_INPUT
rotateFactor_ = 1;
rotateThreshold_ = 1;
#endif
#if ENABLE_FOCUS_MANAGER
focusable_ = true;
#endif
isViewGroup_ = true;
touchable_ = true;
......
......@@ -118,6 +118,9 @@ UIList::UIList()
#endif
#if ENABLE_MOTOR
motorType_ = MotorType::MOTOR_TYPE_ONE;
#endif
#if ENABLE_FOCUS_MANAGER
focusable_ = true;
#endif
direction_ = VERTICAL;
touchable_ = true;
......@@ -144,6 +147,9 @@ UIList::UIList(uint8_t direction)
#endif
#if ENABLE_MOTOR
motorType_ = MotorType::MOTOR_TYPE_ONE;
#endif
#if ENABLE_FOCUS_MANAGER
focusable_ = true;
#endif
direction_ = direction;
touchable_ = true;
......
......@@ -167,6 +167,9 @@ UIPicker::UIPicker()
#endif
#if ENABLE_MOTOR
list_.SetMotorType(MotorType::MOTOR_TYPE_TWO);
#endif
#if ENABLE_FOCUS_MANAGER
focusable_ = true;
#endif
list_.SetLoopState(false);
list_.EnableAutoAlign(true);
......
......@@ -30,6 +30,9 @@ UIScrollView::UIScrollView()
#if ENABLE_ROTATE_INPUT
rotateFactor_ = 1;
rotateThreshold_ = 4; // 4: which means 25% of half view size
#endif
#if ENABLE_FOCUS_MANAGER
focusable_ = true;
#endif
direction_ = HORIZONTAL_AND_VERTICAL;
xSlider_.SetVisible(false);
......
......@@ -35,6 +35,9 @@ UISlider::UISlider()
} else {
knobStyle_ = &(StyleDefault::GetSliderKnobStyle());
}
#if ENABLE_FOCUS_MANAGER
focusable_ = true;
#endif
}
UISlider::~UISlider()
......
......@@ -31,6 +31,9 @@ UIView::UIView()
needRedraw_(false),
styleAllocFlag_(false),
isIntercept_(true),
#if ENABLE_FOCUS_MANAGER
focusable_(false),
#endif
opaScale_(OPA_OPAQUE),
index_(0),
id_(nullptr),
......@@ -42,6 +45,9 @@ UIView::UIView()
onLongPressListener_(nullptr),
onDragListener_(nullptr),
onTouchListener_(nullptr),
#if ENABLE_FOCUS_MANAGER
onFocusListener_(nullptr),
#endif
#if ENABLE_ROTATE_INPUT
onRotateListener_(nullptr),
#endif
......@@ -400,6 +406,22 @@ void UIView::GetTargetView(const Point& point, UIView** current, UIView** target
}
}
#if ENABLE_FOCUS_MANAGER
void UIView::Focus()
{
if (focusable_ && onFocusListener_ != nullptr) {
onFocusListener_->OnFocus(*this);
}
}
void UIView::Blur()
{
if (onFocusListener_ != nullptr) {
onFocusListener_->OnBlur(*this);
}
}
#endif
Rect UIView::GetRect() const
{
if ((transMap_ != nullptr) && !transMap_->IsInvalid()) {
......
......@@ -24,6 +24,9 @@ UIViewGroup::UIViewGroup()
isDragging_(false), disallowIntercept_(false), isAutoSize_(false)
{
isViewGroup_ = true;
#if ENABLE_FOCUS_MANAGER
isInterceptFocus_ = false;
#endif
}
UIViewGroup::~UIViewGroup() {}
......
/*
* Copyright (c) 2020-2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT 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/focus_manager.h"
#if ENABLE_FOCUS_MANAGER
#include "components/root_view.h"
#include "graphic_math.h"
namespace OHOS {
bool FocusManager::RequestFocus(UIView* view)
{
if (view == nullptr || view == focusView_ || !view->IsFocusable() ||
!view->IsVisible()) {
return false;
}
lastFocusView_ = focusView_;
focusView_ = view;
if (lastFocusView_ != nullptr) {
lastFocusView_->Blur();
}
focusView_->Focus();
return true;
}
bool FocusManager::ClearFocus()
{
if (focusView_ == nullptr) {
return false;
}
lastFocusView_ = focusView_;
focusView_->Blur();
focusView_ = nullptr;
return true;
}
bool FocusManager::RequestFocusByDirection(uint8_t direction)
{
if (focusView_ != nullptr) {
UIView* candidate = nullptr;
if (GetNextFocus(focusView_, candidate, direction)) {
return RequestFocus(candidate);
}
}
return false;
}
bool FocusManager::CompareCandidates(UIView* focusedView, UIView*& candidate, UIView* current, uint8_t direction)
{
if (current == focusedView) {
return false;
}
bool res = false;
switch (direction) {
case FOCUS_DIRECTION_UP: {
res = CompareCandidatesByUp(focusedView, candidate, current);
break;
}
case FOCUS_DIRECTION_DOWN: {
res = CompareCandidatesByDown(focusedView, candidate, current);
break;
}
case FOCUS_DIRECTION_LEFT: {
res = CompareCandidatesByLeft(focusedView, candidate, current);
break;
}
case FOCUS_DIRECTION_RIGHT: {
res = CompareCandidatesByRight(focusedView, candidate, current);
break;
}
default:
return false;
}
return res;
}
bool FocusManager::IsAtSameCol(const Rect& rect1, const Rect& rect2)
{
return ((rect1.GetLeft() < rect2.GetRight()) && (rect1.GetRight() > rect2.GetLeft()));
}
bool FocusManager::IsAtSameRow(const Rect& rect1, const Rect& rect2)
{
return ((rect1.GetBottom() < rect2.GetTop()) && (rect1.GetTop() > rect2.GetBottom()));
}
bool FocusManager::CompareCandidatesByUp(UIView* focusedView, UIView*& candidate, UIView* current)
{
Rect focusedViewRect = focusedView->GetRect();
Rect currentRect = current->GetRect();
if (currentRect.GetBottom() >= focusedViewRect.GetBottom()) {
return false;
}
if (candidate != nullptr) {
Rect candidateRect = candidate->GetRect();
if (IsAtSameCol(focusedViewRect, currentRect) && IsAtSameCol(focusedViewRect, candidateRect)) {
return currentRect.GetBottom() > candidateRect.GetBottom();
}
return CompareCandidatesDistance(focusedViewRect, candidateRect, currentRect);
}
return true;
}
bool FocusManager::CompareCandidatesByDown(UIView* focusedView, UIView*& candidate, UIView* current)
{
Rect focusedViewRect = focusedView->GetRect();
Rect currentRect = current->GetRect();
if (currentRect.GetTop() <= focusedViewRect.GetTop()) {
return false;
}
if (candidate != nullptr) {
Rect candidateRect = candidate->GetRect();
if (IsAtSameCol(focusedViewRect, currentRect) && IsAtSameCol(focusedViewRect, candidateRect)) {
return currentRect.GetTop() < candidateRect.GetTop();
}
return CompareCandidatesDistance(focusedViewRect, candidateRect, currentRect);
}
return true;
}
bool FocusManager::CompareCandidatesByLeft(UIView* focusedView, UIView*& candidate, UIView* current)
{
Rect focusedViewRect = focusedView->GetRect();
Rect currentRect = current->GetRect();
if (currentRect.GetRight() >= focusedViewRect.GetRight()) {
return false;
}
if (candidate != nullptr) {
Rect candidateRect = candidate->GetRect();
if (IsAtSameRow(focusedViewRect, currentRect) && IsAtSameRow(focusedViewRect, candidateRect)) {
return currentRect.GetRight() > candidateRect.GetRight();
}
return CompareCandidatesDistance(focusedViewRect, candidateRect, currentRect);
}
return true;
}
bool FocusManager::CompareCandidatesByRight(UIView* focusedView, UIView*& candidate, UIView* current)
{
Rect focusedViewRect = focusedView->GetRect();
Rect currentRect = current->GetRect();
if (currentRect.GetLeft() <= focusedViewRect.GetLeft()) {
return false;
}
if (candidate != nullptr) {
Rect candidateRect = candidate->GetRect();
if (IsAtSameRow(focusedViewRect, currentRect) && IsAtSameRow(focusedViewRect, candidateRect)) {
return currentRect.GetLeft() < candidateRect.GetLeft();
}
return CompareCandidatesDistance(focusedViewRect, candidateRect, currentRect);
}
return true;
}
bool FocusManager::CompareCandidatesDistance(const Rect& focused, const Rect& candidate, const Rect& current)
{
uint64_t xDiff1 = focused.GetX() - candidate.GetX();
uint64_t yDiff1 = focused.GetY() - candidate.GetY();
uint64_t xDiff2 = focused.GetX() - current.GetX();
uint64_t yDiff2 = focused.GetY() - current.GetY();
uint64_t distance1 = xDiff1 * xDiff1 + yDiff1 * yDiff1;
uint64_t distance2 = xDiff2 * xDiff2 + yDiff2 * yDiff2;
return distance2 < distance1;
}
bool FocusManager::GetNextFocus(UIView* focusedView, UIView*& candidate, uint8_t direction)
{
UIView* parent = focusedView->GetParent();
if (parent == nullptr) {
return false;
}
UIView* child = nullptr;
bool isFoundBestCandidate = false;
UIView* current = focusedView;
while (parent != nullptr) {
if (isFoundBestCandidate) {
return true;
}
child = static_cast<UIViewGroup*>(parent)->GetChildrenHead();
while (child != nullptr) {
if (child == current) {
child = child->GetNextSibling();
continue;
}
if (child->IsViewGroup()) {
if (GetNextFocus(focusedView, candidate, static_cast<UIViewGroup*>(child), direction)) {
isFoundBestCandidate = true;
}
} else {
if (GetNextFocus(focusedView, candidate, child, direction)) {
isFoundBestCandidate = true;
}
}
child = child->GetNextSibling();
}
if (isFoundBestCandidate) {
return true;
} else {
current = parent;
}
parent = parent->GetParent();
}
return false;
}
bool FocusManager::GetNextFocus(UIView* focusedView, UIView*& candidate, UIView* view, uint8_t direction)
{
UIView* current = view;
if (!current->IsVisible() || !current->IsFocusable()) {
return false;
}
if (CompareCandidates(focusedView, candidate, current, direction)) {
candidate = current;
return true;
}
return false;
}
bool FocusManager::GetNextFocus(UIView* focusedView, UIView*& candidate, UIViewGroup* viewGroup, uint8_t direction)
{
UIViewGroup* current = viewGroup;
if (current->IsInterceptFocus()) {
return GetNextFocus(focusedView, candidate, static_cast<UIView*>(current), direction);
}
UIView* child = current->GetChildrenHead();
bool childFocusable = false;
while (child != nullptr) {
if (child == focusedView) {
child = child->GetNextSibling();
continue;
}
if (child->IsViewGroup()) {
if (GetNextFocus(focusedView, candidate, static_cast<UIViewGroup*>(child), direction)) {
childFocusable = true;
}
} else if (GetNextFocus(focusedView, candidate, child, direction)) {
childFocusable = true;
}
child = child->GetNextSibling();
}
return childFocusable;
}
}
#endif
\ No newline at end of file
......@@ -16,9 +16,23 @@
#ifndef GRAPHIC_LITE_FOCUS_MANAGER_H
#define GRAPHIC_LITE_FOCUS_MANAGER_H
#include "components/ui_view.h"
#include "graphic_config.h"
#if ENABLE_FOCUS_MANAGER
#include "components/ui_view_group.h"
namespace OHOS {
/**
* @brief Enumerates focus directions.
*
* @since 5.0
* @version 3.0
*/
enum : uint8_t {
FOCUS_DIRECTION_RIGHT,
FOCUS_DIRECTION_LEFT,
FOCUS_DIRECTION_UP,
FOCUS_DIRECTION_DOWN,
};
#if ENABLE_MOTOR
/**
* @brief 震动类型.
......@@ -41,25 +55,59 @@ typedef void(*MotorFunc)(MotorType motorType);
class FocusManager {
public:
/**
* @brief Get the FocusManager's singleton.
*
* @return FocusManager's singleton.
* @since 5.0
* @version 3.0
*/
static FocusManager* GetInstance()
{
static FocusManager instance;
return &instance;
}
void ClearFocus()
{
view_ = nullptr;
}
/**
* @brief Clear the focus.
*
* @return Returns <b>true</b> if the operation is successful; returns <b>false</b> otherwise.
* @since 5.0
* @version 3.0
*/
bool ClearFocus();
/**
* @brief Get the focused view.
*
* @return the focused view.
* @since 5.0
* @version 3.0
*/
UIView* GetFocusedView()
{
return view_;
return focusView_;
}
void RequestFocus(UIView* view)
{
view_ = view;
}
/**
* @brief Request the focus.
*
* @param view the focus.
* @return Returns <b>true</b> if the operation is successful; returns <b>false</b> otherwise.
* @since 5.0
* @version 3.0
*/
bool RequestFocus(UIView* view);
/**
* @brief Request focus by direction.
*
* @param direction focus direction.
* @return Returns <b>true</b> if the operation is successful; returns <b>false</b> otherwise.
* @since 5.0
* @version 3.0
*/
bool RequestFocusByDirection(uint8_t direction);
#if ENABLE_MOTOR
void RegisterMotorFunc(MotorFunc motorFunc)
......@@ -74,12 +122,27 @@ public:
#endif
private:
FocusManager() : view_(nullptr) {}
FocusManager() : focusView_(nullptr), lastFocusView_(nullptr) {}
~FocusManager() {}
UIView* view_;
bool GetNextFocus(UIView* focusedView, UIView*& candidate, uint8_t direction);
bool GetNextFocus(UIView* focusedView, UIView*& candidate, UIView* view, uint8_t direction);
bool GetNextFocus(UIView* focusedView, UIView*& candidate, UIViewGroup* viewGroup, uint8_t direction);
bool IsAtSameCol(const Rect& rect1, const Rect& rect2);
bool IsAtSameRow(const Rect& rect1, const Rect& rect2);
bool CompareCandidates(UIView* focusedView, UIView*& candidate, UIView* current, uint8_t direction);
bool CompareCandidatesByUp(UIView* focusedView, UIView*& candidate, UIView* current);
bool CompareCandidatesByDown(UIView* focusedView, UIView*& candidate, UIView* current);
bool CompareCandidatesByLeft(UIView* focusedView, UIView*& candidate, UIView* current);
bool CompareCandidatesByRight(UIView* focusedView, UIView*& candidate, UIView* current);
bool CompareCandidatesDistance(const Rect& focused, const Rect& candidate, const Rect& current);
UIView* focusView_;
UIView* lastFocusView_;
#if ENABLE_MOTOR
MotorFunc motorFunc_ = nullptr;
#endif
};
} // namespace OHOS
#endif // GRAPHIC_LITE_FOCUS_MANAGER_H
#endif
#endif // GRAPHIC_LITE_FOCUS_MANAGER_H
\ No newline at end of file
......@@ -1478,6 +1478,107 @@ public:
*/
virtual void ClearFocus();
#endif
#if ENABLE_FOCUS_MANAGER
/**
* @brief 设置视图是否可获焦.
*
* @param focusable 是否可获焦.
* @since 5.0
* @version 3.0
*/
void SetFocusable(bool focusable)
{
focusable_ = focusable;
}
/**
* @brief 获取视图是否可获焦.
*
* @return 是否可获焦.
* @since 5.0
* @version 3.0
*/
bool IsFocusable() const
{
return focusable_;
}
/**
* @brief 组件获焦响应
*
* @since 5.0
* @version 3.0
*/
void Focus();
/**
* @brief 组件失焦响应
*
* @since 5.0
* @version 3.0
*/
void Blur();
/**
* @brief 焦点改变事件监听类,开发者需要向视图组件注册该类实现事件的监听.
*
* @since 5.0
* @version 3.0
*/
class OnFocusListener : public HeapBase {
public:
/**
* @brief 回调函数,视图获焦时触发.
* @param view 获焦的视图
* @since 5.0
* @version 3.0
*/
virtual bool OnFocus(UIView& view)
{
return false;
}
/**
* @brief 回调函数,视图失焦时触发.
* @param view 失焦的视图
* @since 5.0
* @version 3.0
*/
virtual bool OnBlur(UIView& view)
{
return false;
}
/**
* @brief 析构函数.
* @since 5.0
* @version 3.0
*/
virtual ~OnFocusListener() {}
};
/**
* @brief 设置当前视图焦点改变事件监听者.
* @param onFocusListener 焦点改变事件监听者.
* @since 5.0
* @version 3.0
*/
void SetOnFocusListener(OnFocusListener* onFocusListener)
{
onFocusListener_ = onFocusListener;
}
/**
* @brief 获取当前视图焦点改变事件监听者.
* @return 焦点改变事件监听者.
* @since 5.0
* @version 3.0
*/
OnFocusListener* GetOnFocusListener() const
{
return onFocusListener_;
}
#endif
protected:
bool touchable_ : 1;
......@@ -1488,6 +1589,9 @@ protected:
bool needRedraw_ : 1;
bool styleAllocFlag_ : 1;
bool isIntercept_ : 1;
#if ENABLE_FOCUS_MANAGER
bool focusable_ : 1;
#endif
uint8_t opaScale_;
int16_t index_;
const char* id_;
......@@ -1499,6 +1603,9 @@ protected:
OnLongPressListener* onLongPressListener_;
OnDragListener* onDragListener_;
OnTouchListener* onTouchListener_;
#if ENABLE_FOCUS_MANAGER
OnFocusListener* onFocusListener_;
#endif
#if ENABLE_ROTATE_INPUT
OnRotateListener* onRotateListener_;
#endif
......
......@@ -210,6 +210,32 @@ public:
isAutoSize_ = state;
}
#if ENABLE_FOCUS_MANAGER
/**
* @brief 设置组件是否拦截焦点.
*
* @param interceptFocus 是否拦截焦点.
* @since 5.0
* @version 3.0
*/
void SetInterceptFocus(bool interceptFocus)
{
isInterceptFocus_ = interceptFocus;
}
/**
* @brief 获取组件是否拦截焦点.
*
* @return 是否为焦点.
* @since 5.0
* @version 3.0
*/
bool IsInterceptFocus() const
{
return isInterceptFocus_;
}
#endif
protected:
/**
* @brief Obtains the rectangle area of a new view group after being adaptive to the size of all child views.
......@@ -260,6 +286,9 @@ protected:
private:
void AutoResize();
#if ENABLE_FOCUS_MANAGER
bool isInterceptFocus_ : 1;
#endif
};
} // namespace OHOS
#endif // GRAPHIC_LITE_UI_VIEW_GROUP_H
......@@ -26,6 +26,7 @@ static_library("framework") {
"../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_focus_manager/ui_test_focus_manager.cpp",
"../uitest/test_font/ui_test_font.cpp",
"../uitest/test_image/ui_test_image.cpp",
"../uitest/test_image_animator/ui_test_image_animator.cpp",
......
......@@ -50,13 +50,13 @@ public:
virtual ~UITest() {}
/**
* @brief Set up display enviroment.
* @brief Set up display environment.
*
*/
virtual void SetUp() = 0;
/**
* @brief Tear down display enviroment.
* @brief Tear down display environment.
*
*/
virtual void TearDown() = 0;
......
......@@ -28,6 +28,9 @@
#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"
#if ENABLE_FOCUS_MANAGER
#include "test_focus_manager/ui_test_focus_manager.h"
#endif
#include "test_font/ui_test_font.h"
#include "test_image/ui_test_image.h"
#include "test_image_animator/ui_test_image_animator.h"
......@@ -130,6 +133,9 @@ void UITestGroup::SetUpTestCase()
#ifndef VERSION_LITE
testCaseList_.PushBack(TestCaseInfo{"Video", new UITestVideo()});
#endif
#if ENABLE_FOCUS_MANAGER
testCaseList_.PushBack(TestCaseInfo{"FocusManager", new UITestFocusManager()});
#endif
}
List<TestCaseInfo>& UITestGroup::GetTestCase()
......
/*
* Copyright (c) 2020-2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT 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_focus_manager.h"
#if ENABLE_FOCUS_MANAGER
namespace OHOS {
namespace {
const uint16_t LABEL_BUTTON_DEFAULT_FONT_SIZE = 15;
const uint16_t LABEL_BUTTON_DEFAULT_WIDTH = 60;
const uint16_t LABEL_BUTTON_DEFAULT_HEIGHT = 40;
} // namespace
class TestOnFocusListener : public UIView::OnFocusListener {
public:
TestOnFocusListener() {}
~TestOnFocusListener() {}
bool OnFocus(UIView& view) override
{
if (view.IsViewGroup()) {
view.SetStyle(STYLE_BORDER_COLOR, Color::Red().full);
} else {
view.SetStyle(STYLE_BACKGROUND_COLOR, Color::Red().full);
}
view.Invalidate();
return true;
}
bool OnBlur(UIView& view) override
{
if (view.IsViewGroup()) {
view.SetStyle(STYLE_BORDER_COLOR, Color::White().full);
} else {
/* 0: red, 125: green, 255: blue */
view.SetStyle(STYLE_BACKGROUND_COLOR, Color::GetColorFromRGB(0, 125, 255).full);
}
view.Invalidate();
return true;
}
};
class RequestFocusByDirectionOnClickListener : public UIView::OnClickListener {
public:
explicit RequestFocusByDirectionOnClickListener(uint8_t direction) : direction_(direction) {}
~RequestFocusByDirectionOnClickListener() {}
bool OnClick(UIView& view, const ClickEvent& event)
{
FocusManager::GetInstance()->RequestFocusByDirection(direction_);
return true;
}
private:
uint8_t direction_ = 0;
};
class ResetFocusOnClickListener : public UIView::OnClickListener {
public:
explicit ResetFocusOnClickListener(UIView* focus) : focus_(focus) {}
~ResetFocusOnClickListener() {}
bool OnClick(UIView& view, const ClickEvent& event)
{
FocusManager::GetInstance()->RequestFocus(focus_);
return true;
}
private:
UIView* focus_ = nullptr;
};
class SetGroupInterceptOnClickListener : public UIView::OnClickListener {
public:
SetGroupInterceptOnClickListener(UIViewGroup* viewGroup, bool intercept)
: viewGroup_(viewGroup), intercept_(intercept) {}
~SetGroupInterceptOnClickListener() {}
bool OnClick(UIView& view, const ClickEvent& event)
{
if (viewGroup_ != nullptr) {
viewGroup_->SetInterceptFocus(intercept_);
return true;
}
return false;
}
private:
UIViewGroup* viewGroup_ = nullptr;
bool intercept_;
};
class SetGroupInterceptFalseOnClickListener : public UIView::OnClickListener {
public:
explicit SetGroupInterceptFalseOnClickListener(UIViewGroup* viewGroup) : viewGroup_(viewGroup) {}
~SetGroupInterceptFalseOnClickListener() {}
bool OnClick(UIView& view, const ClickEvent& event)
{
viewGroup_->SetInterceptFocus(false);
}
private:
UIViewGroup* viewGroup_ = nullptr;
};
class SetFocusableOnClickListener : public UIView::OnClickListener {
public:
SetFocusableOnClickListener(UIView* view, bool enable) : view_(view), enable_(enable) {}
~SetFocusableOnClickListener() {}
bool OnClick(UIView& view, const ClickEvent& event)
{
view_->SetFocusable(enable_);
return true;
}
private:
UIView* view_ = nullptr;
bool enable_ = false;
};
class RequestFocusOnClickListener : public UIView::OnClickListener {
public:
explicit RequestFocusOnClickListener(UIView* view) : view_(view) {}
~RequestFocusOnClickListener() {}
bool OnClick(UIView& view, const ClickEvent& event)
{
FocusManager::GetInstance()->RequestFocus(view_);
return true;
}
private:
UIView* view_ = nullptr;
};
class ClearFocusOnClickListener : public UIView::OnClickListener {
public:
ClearFocusOnClickListener() {}
~ClearFocusOnClickListener() {}
bool OnClick(UIView& view, const ClickEvent& event)
{
FocusManager::GetInstance()->ClearFocus();
return true;
}
};
void UITestFocusManager::SetUp()
{
if (container_ == nullptr) {
container_ = new UIScrollView();
container_->Resize(Screen::GetInstance().GetWidth(), Screen::GetInstance().GetHeight() - BACK_BUTTON_HEIGHT);
container_->SetHorizontalScrollState(false);
}
}
void UITestFocusManager::TearDown()
{
FocusManager::GetInstance()->ClearFocus();
DeleteChildren(container_);
container_ = nullptr;
}
const UIView* UITestFocusManager::GetTestView()
{
UIKit_Focus_Manager_Test_001();
return container_;
}
UIView* UITestFocusManager::CreateTestUILabel(UIViewGroup* parent, int16_t x, int16_t y,
const char* text, bool focusable)
{
UILabel* label = new UILabel();
parent->Add(label);
label->SetPosition(x, y, LABEL_BUTTON_DEFAULT_WIDTH, LABEL_BUTTON_DEFAULT_HEIGHT);
label->SetText(text);
label->SetViewId(text);
label->SetFont(DEFAULT_VECTOR_FONT_FILENAME, LABEL_BUTTON_DEFAULT_FONT_SIZE);
label->SetFocusable(focusable);
/* 0: red, 125: green, 255: blue */
label->SetStyle(STYLE_BACKGROUND_COLOR, Color::GetColorFromRGB(0, 125, 255).full);
label->SetStyle(STYLE_BACKGROUND_OPA, OPA_OPAQUE);
label->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER);
TestOnFocusListener* testOnFocusListener = new TestOnFocusListener();
label->SetOnFocusListener(testOnFocusListener);
return label;
}
UIViewGroup* UITestFocusManager::CreateTestUIViewGroup(UIViewGroup* parent, bool focusable, bool interceptFocus)
{
UIViewGroup* viewGroup = new UIViewGroup();
parent->Add(viewGroup);
viewGroup->SetFocusable(focusable);
viewGroup->SetInterceptFocus(interceptFocus);
viewGroup->SetStyle(STYLE_BORDER_COLOR, Color::White().full);
viewGroup->SetStyle(STYLE_BORDER_OPA, HALF_OPA_OPAQUE);
viewGroup->SetStyle(STYLE_BORDER_WIDTH, 1);
viewGroup->SetStyle(STYLE_BORDER_RADIUS, VIEW_STYLE_BORDER_RADIUS);
TestOnFocusListener* testOnFocusListener = new TestOnFocusListener();
viewGroup->SetOnFocusListener(testOnFocusListener);
return viewGroup;
}
void UITestFocusManager::UIKit_Focus_Manager_Test_001()
{
UILabel* label = new UILabel();
container_->Add(label);
/* 288: width */
label->SetPosition(TEXT_DISTANCE_TO_LEFT_SIDE, TEXT_DISTANCE_TO_TOP_SIDE, 288, TITLE_LABEL_DEFAULT_HEIGHT);
label->SetText("焦点管理效果 ");
label->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE);
UIViewGroup* viewGroup = CreateTestUIViewGroup(container_, true, false);
/* 600: width, 350: height */
viewGroup->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE2, VIEW_DISTANCE_TO_TOP_SIDE, 600, 350);
UIViewGroup* viewGroup1 = CreateTestUIViewGroup(viewGroup, true, false);
UIViewGroup* viewGroup2 = CreateTestUIViewGroup(viewGroup1, true, false);
UIViewGroup* viewGroup3 = CreateTestUIViewGroup(viewGroup, true, false);
UIViewGroup* viewGroup4 = CreateTestUIViewGroup(viewGroup3, true, false);
UIViewGroup* viewGroup5 = CreateTestUIViewGroup(viewGroup4, true, false);
UIViewGroup* viewGroup6 = CreateTestUIViewGroup(viewGroup, true, false);
viewGroup1->SetPosition(5, 5, 270, 60); /* 5: x, 5: y; 270: width, 60: height */
viewGroup2->SetPosition(100, 5, 80, 50); /* 100: x, 5: y; 80: width, 50: height */
viewGroup3->SetPosition(290, 5, 280, 115); /* 290: x, 5: y; 280: width, 115: height */
viewGroup4->SetPosition(5, 5, 260, 60); /* 5: x, 5: y; 260: width, 60: height */
viewGroup5->SetPosition(5, 5, 250, 50); /* 5: x, 5: y; 250: width, 50: height */
viewGroup6->SetPosition(100, 160, 400, 160); /* 100: x, 160: y; 400: width, 160: height */
CreateTestUILabel(viewGroup1, 0, 5, "1", true); /* 0: x, 5: y */
UIView* view2 = CreateTestUILabel(viewGroup1, 195, 5, "2", true); /* 195: x, 5: y */
CreateTestUILabel(viewGroup2, 5, 5, "3", true); /* 5: x, 5: y */
CreateTestUILabel(viewGroup5, 5, 5, "4", true); /* 5: x, 5: y */
CreateTestUILabel(viewGroup5, 180, 5, "5", true); /* 180: x, 5: y */
CreateTestUILabel(viewGroup3, 150, 70, "6", true); /* 150: x, 70: y */
CreateTestUILabel(viewGroup, 80, 100, "7", true); /* 80: x, 100: y */
CreateTestUILabel(viewGroup6, 5, 5, "8", true); /* 5: x, 5: y */
CreateTestUILabel(viewGroup6, 100, 80, "9", true); /* 100: x, 80: y */
CreateTestUILabel(viewGroup6, 300, 5, "10", true); /* 300: x, 5: y */
UIViewGroup* btnViewGroup = new UIViewGroup();
/* 650: x, 300: width, 400: height */
btnViewGroup->SetPosition(650, VIEW_DISTANCE_TO_TOP_SIDE, 300, 400);
container_->Add(btnViewGroup);
UILabelButton* leftBtn = new UILabelButton();
/* 10: x, 10: y */
SetUpButton("向左 ", 10, 10, btnViewGroup, new RequestFocusByDirectionOnClickListener(FOCUS_DIRECTION_LEFT));
/* 150: x, 10: y */
SetUpButton("向右 ", 150, 10, btnViewGroup, new RequestFocusByDirectionOnClickListener(FOCUS_DIRECTION_RIGHT));
/* 10: x, 60: y */
SetUpButton("向上 ", 10, 60, btnViewGroup, new RequestFocusByDirectionOnClickListener(FOCUS_DIRECTION_UP));
/* 150: x, 60: y */
SetUpButton("向下 ", 150, 60, btnViewGroup, new RequestFocusByDirectionOnClickListener(FOCUS_DIRECTION_DOWN));
/* 10: x, 110: y */
SetUpButton("2可获焦 ", 10, 110, btnViewGroup, new SetFocusableOnClickListener(view2, true));
/* 150: x, 110: y */
SetUpButton("2不可获焦 ", 150, 110, btnViewGroup, new SetFocusableOnClickListener(view2, false));
/* 10: x, 160: y */
SetUpButton("设置4容器拦截 ", 10, 160, btnViewGroup, new SetGroupInterceptOnClickListener(viewGroup5, true));
/* 150: x, 160: y */
SetUpButton("取消4容器拦截 ", 150, 160, btnViewGroup, new SetGroupInterceptOnClickListener(viewGroup5, false));
/* 10: x, 210: y */
SetUpButton("重置焦点 ", 10, 210, btnViewGroup, new ResetFocusOnClickListener(viewGroup1->GetChildById("1")));
/* 150: x, 210: y */
SetUpButton("清除焦点 ", 150, 210, btnViewGroup, new ClearFocusOnClickListener());
FocusManager::GetInstance()->RequestFocus(viewGroup1->GetChildById("1"));
}
UILabelButton* UITestFocusManager::SetUpButton(const char* title, int16_t x, int16_t y, UIViewGroup* viewGroup,
UIView::OnClickListener* listener)
{
UILabelButton* btn = new UILabelButton();
btn->SetPosition(x, y, BUTTON_WIDHT2, BUTTON_HEIGHT1);
btn->SetText(title);
btn->SetFont(DEFAULT_VECTOR_FONT_FILENAME, BUTTON_LABEL_SIZE);
btn->SetOnClickListener(listener);
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);
viewGroup->Add(btn);
return btn;
}
} // namespace OHOS
#endif
\ No newline at end of file
/*
* Copyright (c) 2020-2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT 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_FOCUS_MANAGER_H
#define UI_TEST_FOCUS_MANAGER_H
#include "graphic_config.h"
#if ENABLE_FOCUS_MANAGER
#include "components/ui_label_button.h"
#include "components/ui_scroll_view.h"
#include "dock/focus_manager.h"
#include "ui_test.h"
namespace OHOS {
class UITestFocusManager : public UITest {
public:
UITestFocusManager() {}
~UITestFocusManager() {}
void SetUp() override;
void TearDown() override;
const UIView* GetTestView();
void UIKit_Focus_Manager_Test_001();
private:
UIView* CreateTestUILabel(UIViewGroup* parent, int16_t x, int16_t y,
const char* text, bool focusable);
UIViewGroup* CreateTestUIViewGroup(UIViewGroup* parent, bool focusable, bool interceptFocus);
UILabelButton* SetUpButton(const char* title, int16_t x, int16_t y, UIViewGroup* viewGroup,
UIView::OnClickListener* listener);
UIScrollView* container_ = nullptr;
};
} // namespace OHOS
#endif
#endif // UI_TEST_FOCUS_MANAGER_H
\ No newline at end of file
......@@ -23,6 +23,7 @@ group("lite_graphic_ui_test") {
":graphic_test_dfx",
":graphic_test_dialog",
":graphic_test_events",
":graphic_test_focus_manager",
":graphic_test_font",
":graphic_test_image",
":graphic_test_label",
......@@ -284,4 +285,12 @@ if (ohos_build_type == "debug") {
deps = commonDeps
sources = [ "rotate/ui_rotate_input_unit_test.cpp" ]
}
unittest("graphic_test_focus_manager") {
output_extension = "bin"
output_dir = "$root_out_dir/test/unittest/graphic"
configs = [ ":graphic_test_config" ]
deps = commonDeps
sources = [ "common/focus_manager_unit_test.cpp" ]
}
}
/*
* Copyright (c) 2020-2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT 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 "dock/focus_manager.h"
#include <climits>
#include <gtest/gtest.h>
#if ENABLE_FOCUS_MANAGER
using namespace testing::ext;
namespace OHOS {
class FocusManagerTest : public testing::Test {
public:
static void SetUpTestCase(void);
static void TearDownTestCase(void);
static UIViewGroup* viewGroup_;
static UILabel* label1_;
static UILabel* label2_;
};
UIViewGroup* FocusManagerTest::viewGroup_ = nullptr;
UILabel* FocusManagerTest::label1_ = nullptr;
UILabel* FocusManagerTest::label2_ = nullptr;
void FocusManagerTest::SetUpTestCase(void)
{
if (viewGroup_ == nullptr) {
viewGroup_ = new UIViewGroup();
viewGroup_->SetPosition(0, 0, 200, 200); // 200: width, 200: height
}
if (label1_ == nullptr) {
label1_ = new UILabel();
label1_->SetFocusable(true);
label1_->SetPosition(50, 50, 50, 50); // 50: x, 50: y, 50: width, 50: height
}
if (label2_ == nullptr) {
label2_ = new UILabel();
label2_->SetFocusable(true);
label2_->SetPosition(150, 150, 50, 50); // 150: x, 150: y, 50: width, 50: height
}
viewGroup_->Add(label1_);
viewGroup_->Add(label2_);
}
void FocusManagerTest::TearDownTestCase(void)
{
if (viewGroup_ != nullptr) {
viewGroup_->Remove(label1_);
viewGroup_->Remove(label2_);
delete viewGroup_;
viewGroup_ = nullptr;
}
if (label1_ != nullptr) {
delete label1_;
label1_ = nullptr;
}
if (label2_ != nullptr) {
delete label2_;
label2_ = nullptr;
}
FocusManager::GetInstance()->ClearFocus();
}
/**
* @tc.name: GetFocusedView_001
* @tc.desc: Verify GetFocusedView function, equal.
* @tc.type: FUNC
* @tc.require: AR000EVI2R
*/
HWTEST_F(FocusManagerTest, GetFocusedView_001, TestSize.Level0)
{
UIView* focusedView = FocusManager::GetInstance()->GetFocusedView();
EXPECT_EQ(focusedView, nullptr);
}
/**
* @tc.name: RequestFocus_001
* @tc.desc: Verify RequestFocus function, equal.
* @tc.type: FUNC
* @tc.require: AR000EVI2R
*/
HWTEST_F(FocusManagerTest, RequestFocus_001, TestSize.Level0)
{
FocusManager::GetInstance()->RequestFocus(label1_);
UIView* focusedView = FocusManager::GetInstance()->GetFocusedView();
EXPECT_EQ(focusedView, label1_);
FocusManager::GetInstance()->RequestFocus(label2_);
focusedView = FocusManager::GetInstance()->GetFocusedView();
EXPECT_EQ(focusedView, label2_);
}
/**
* @tc.name: ClearFocus_001
* @tc.desc: Verify ClearFocus function, equal.
* @tc.type: FUNC
* @tc.require: AR000EVI2R
*/
HWTEST_F(FocusManagerTest, ClearFocus_001, TestSize.Level0)
{
FocusManager::GetInstance()->RequestFocus(label1_);
UIView* focusedView = FocusManager::GetInstance()->GetFocusedView();
EXPECT_EQ(focusedView, label1_);
FocusManager::GetInstance()->ClearFocus();
focusedView = FocusManager::GetInstance()->GetFocusedView();
EXPECT_EQ(focusedView, nullptr);
}
/**
* @tc.name: RequestFocusByDirection_001
* @tc.desc: Verify RequestFocusByDirection function, equal.
* @tc.type: FUNC
* @tc.require: AR000EVI2R
*/
HWTEST_F(FocusManagerTest, RequestFocusByDirection_001, TestSize.Level0)
{
FocusManager::GetInstance()->RequestFocus(label1_);
UIView* focusedView = FocusManager::GetInstance()->GetFocusedView();
EXPECT_EQ(focusedView, label1_);
FocusManager::GetInstance()->RequestFocusByDirection(FOCUS_DIRECTION_RIGHT);
focusedView = FocusManager::GetInstance()->GetFocusedView();
EXPECT_EQ(focusedView, label2_);
FocusManager::GetInstance()->RequestFocusByDirection(FOCUS_DIRECTION_LEFT);
focusedView = FocusManager::GetInstance()->GetFocusedView();
EXPECT_EQ(focusedView, label1_);
FocusManager::GetInstance()->RequestFocusByDirection(FOCUS_DIRECTION_DOWN);
focusedView = FocusManager::GetInstance()->GetFocusedView();
EXPECT_EQ(focusedView, label2_);
FocusManager::GetInstance()->RequestFocusByDirection(FOCUS_DIRECTION_UP);
focusedView = FocusManager::GetInstance()->GetFocusedView();
EXPECT_EQ(focusedView, label1_);
}
} // namespace OHOS
#endif
\ No newline at end of file
......@@ -66,6 +66,7 @@ SOURCES += \
../../../../frameworks/components/ui_toggle_button.cpp \
../../../../frameworks/components/ui_view.cpp \
../../../../frameworks/components/ui_view_group.cpp \
../../../../frameworks/dock/focus_manager.cpp \
../../../../frameworks/core/render_manager.cpp \
../../../../frameworks/core/task_manager.cpp \
../../../../frameworks/default_resource/check_box_res.cpp \
......
......@@ -37,6 +37,7 @@ SOURCES += \
../../../../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_focus_manager/ui_test_focus_manager.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 \
......@@ -82,6 +83,7 @@ HEADERS += \
../../../../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_focus_manager/ui_test_focus_manager.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 \
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册