1 /*
2  * Copyright (c) 2022 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 #ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_RENDER_ADAPTER_FOCUS_STATE_MODIFIER_H
16 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_RENDER_ADAPTER_FOCUS_STATE_MODIFIER_H
17 
18 #include "render_service_client/core/modifier/rs_extended_modifier.h"
19 #include "render_service_client/core/modifier/rs_property.h"
20 #include "render_service_client/core/ui/rs_node.h"
21 
22 #include "core/components_ng/property/gradient_property.h"
23 #include "core/components_ng/render/adapter/rosen_modifier_adapter.h"
24 
25 namespace OHOS::Ace::NG {
26 
27 using RSModifierType = Rosen::RSModifierType;
28 using RSExtendedModifier = Rosen::RSExtendedModifier;
29 using RSPropertyBase = Rosen::RSPropertyBase;
30 
31 class RS_EXPORT FocusStateModifier : public RSOverlayStyleModifier {
32 public:
33     FocusStateModifier() = default;
34 
GetModifierType()35     RSModifierType GetModifierType() const override
36     {
37         return RSModifierType::OVERLAY_STYLE;
38     }
39 
Draw(RSDrawingContext & context)40     void Draw(RSDrawingContext& context) const override
41     {
42         CHECK_NULL_VOID(animationRect_);
43         RSRoundRect roundRect = roundRect_;
44         auto realRect = animationRect_->Get();
45         roundRect.SetRect(
46             RSRect(realRect.Left(), realRect.Top(), realRect.Right(), realRect.Bottom()));
47 #ifndef USE_ROSEN_DRAWING
48         std::shared_ptr<SkCanvas> skCanvas { context.canvas, [](SkCanvas* /*unused*/) {} };
49         RSCanvas rsCanvas(&skCanvas);
50         CHECK_NULL_VOID(&rsCanvas);
51         paintTask_(roundRect, rsCanvas);
52 #else
53         CHECK_NULL_VOID(context.canvas);
54         CHECK_NULL_VOID(paintTask_);
55         paintTask_(roundRect, *context.canvas);
56 #endif
57     }
58 
GetOverlayRect()59     std::shared_ptr<Rosen::RectF> GetOverlayRect()
60     {
61         return overlayRect_;
62     }
63 
SetRoundRect(const RoundRect & rect,float borderWidth)64     void SetRoundRect(const RoundRect& rect, float borderWidth)
65     {
66 #ifndef USE_ROSEN_DRAWING
67 #ifndef USE_GRAPHIC_TEXT_GINE
68         roundRect_.SetRect(
69             rosen::Rect(rect.GetRect().Left(), rect.GetRect().Top(), rect.GetRect().Right(), rect.GetRect().Bottom()));
70         roundRect_.SetCornerRadius(rosen::RoundRect::CornerPos::TOP_LEFT_POS,
71             rect.GetCornerRadius(RoundRect::CornerPos::TOP_LEFT_POS).x,
72             rect.GetCornerRadius(RoundRect::CornerPos::TOP_LEFT_POS).y);
73         roundRect_.SetCornerRadius(rosen::RoundRect::CornerPos::TOP_RIGHT_POS,
74             rect.GetCornerRadius(RoundRect::CornerPos::TOP_RIGHT_POS).x,
75             rect.GetCornerRadius(RoundRect::CornerPos::TOP_RIGHT_POS).y);
76         roundRect_.SetCornerRadius(rosen::RoundRect::CornerPos::BOTTOM_LEFT_POS,
77             rect.GetCornerRadius(RoundRect::CornerPos::BOTTOM_LEFT_POS).x,
78             rect.GetCornerRadius(RoundRect::CornerPos::BOTTOM_LEFT_POS).y);
79         roundRect_.SetCornerRadius(rosen::RoundRect::CornerPos::BOTTOM_RIGHT_POS,
80             rect.GetCornerRadius(RoundRect::CornerPos::BOTTOM_RIGHT_POS).x,
81             rect.GetCornerRadius(RoundRect::CornerPos::BOTTOM_RIGHT_POS).y);
82 #else
83         roundRect_.SetRect(
84             RSRect(rect.GetRect().Left(), rect.GetRect().Top(), rect.GetRect().Right(), rect.GetRect().Bottom()));
85         roundRect_.SetCornerRadius(RSRoundRect::CornerPos::TOP_LEFT_POS,
86             rect.GetCornerRadius(RoundRect::CornerPos::TOP_LEFT_POS).x,
87             rect.GetCornerRadius(RoundRect::CornerPos::TOP_LEFT_POS).y);
88         roundRect_.SetCornerRadius(RSRoundRect::CornerPos::TOP_RIGHT_POS,
89             rect.GetCornerRadius(RoundRect::CornerPos::TOP_RIGHT_POS).x,
90             rect.GetCornerRadius(RoundRect::CornerPos::TOP_RIGHT_POS).y);
91         roundRect_.SetCornerRadius(RSRoundRect::CornerPos::BOTTOM_LEFT_POS,
92             rect.GetCornerRadius(RoundRect::CornerPos::BOTTOM_LEFT_POS).x,
93             rect.GetCornerRadius(RoundRect::CornerPos::BOTTOM_LEFT_POS).y);
94         roundRect_.SetCornerRadius(RSRoundRect::CornerPos::BOTTOM_RIGHT_POS,
95             rect.GetCornerRadius(RoundRect::CornerPos::BOTTOM_RIGHT_POS).x,
96             rect.GetCornerRadius(RoundRect::CornerPos::BOTTOM_RIGHT_POS).y);
97 #endif
98 #else
99         roundRect_.SetRect(
100             RSRect(rect.GetRect().Left(), rect.GetRect().Top(), rect.GetRect().Right(), rect.GetRect().Bottom()));
101         roundRect_.SetCornerRadius(RSRoundRect::CornerPos::TOP_LEFT_POS,
102             rect.GetCornerRadius(RoundRect::CornerPos::TOP_LEFT_POS).x,
103             rect.GetCornerRadius(RoundRect::CornerPos::TOP_LEFT_POS).y);
104         roundRect_.SetCornerRadius(RSRoundRect::CornerPos::TOP_RIGHT_POS,
105             rect.GetCornerRadius(RoundRect::CornerPos::TOP_RIGHT_POS).x,
106             rect.GetCornerRadius(RoundRect::CornerPos::TOP_RIGHT_POS).y);
107         roundRect_.SetCornerRadius(RSRoundRect::CornerPos::BOTTOM_LEFT_POS,
108             rect.GetCornerRadius(RoundRect::CornerPos::BOTTOM_LEFT_POS).x,
109             rect.GetCornerRadius(RoundRect::CornerPos::BOTTOM_LEFT_POS).y);
110         roundRect_.SetCornerRadius(RSRoundRect::CornerPos::BOTTOM_RIGHT_POS,
111             rect.GetCornerRadius(RoundRect::CornerPos::BOTTOM_RIGHT_POS).x,
112             rect.GetCornerRadius(RoundRect::CornerPos::BOTTOM_RIGHT_POS).y);
113 #endif
114         if (!rect_) {
115             rect_ = std::make_shared<Rosen::RSProperty<RectF>>(rect.GetRect());
116         } else {
117             rect_->Set(rect.GetRect());
118         }
119         AttachProperty(rect_);
120 
121         if (!animationRect_) {
122             animationRect_ = std::make_shared<Rosen::RSAnimatableProperty<RectF>>(rect.GetRect());
123         } else {
124             animationRect_->Set(rect.GetRect());
125         }
126 
127         overlayRect_ = std::make_shared<Rosen::RectF>(
128             rect.GetRect().Left() - borderWidth / 2, rect.GetRect().Top() - borderWidth / 2,
129             rect.GetRect().Width() + borderWidth, rect.GetRect().Height() + borderWidth);
130     }
131 
SetPaintTask(const std::function<void (const RSRoundRect &,RSCanvas &)> & paintTask)132     void SetPaintTask(const std::function<void(const RSRoundRect&, RSCanvas&)>& paintTask)
133     {
134         paintTask_ = paintTask;
135     }
136 
AttachAnimationRectProperty()137     void AttachAnimationRectProperty()
138     {
139         AttachProperty(animationRect_);
140     }
141 private:
142     std::shared_ptr<Rosen::RSProperty<RectF>> rect_;
143     RSRoundRect roundRect_;
144     std::shared_ptr<Rosen::RectF> overlayRect_;
145     std::function<void(const RSRoundRect&, RSCanvas&)> paintTask_;
146 
147     // Animation Properties
148     std::shared_ptr<Rosen::RSAnimatableProperty<RectF>> animationRect_;
149     ACE_DISALLOW_COPY_AND_MOVE(FocusStateModifier);
150 };
151 } // namespace OHOS::Ace::NG
152 
153 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_RENDER_ADAPTER_FOCUS_STATE_MODIFIER_H
154