• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 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 "core/components_ng/pattern/select_overlay/select_overlay_content_modifier.h"
17 #include <algorithm>
18 
19 #include "base/geometry/ng/offset_t.h"
20 #include "base/utils/utils.h"
21 #include "core/components/common/properties/color.h"
22 #include "core/components/text_overlay/text_overlay_theme.h"
23 #include "core/components_ng/base/modifier.h"
24 #include "core/components_ng/pattern/select_overlay/select_overlay_layout_algorithm.h"
25 #include "core/components_ng/pattern/select_overlay/select_overlay_paint_method.h"
26 #include "core/components_ng/render/drawing.h"
27 
28 namespace OHOS::Ace::NG {
SelectOverlayContentModifier()29 SelectOverlayContentModifier::SelectOverlayContentModifier()
30     : inShowArea_(AceType::MakeRefPtr<PropertyBool>(false)),
31       handleReverse_(AceType::MakeRefPtr<PropertyBool>(false)),
32       isSingleHandle_(AceType::MakeRefPtr<PropertyBool>(false)),
33       firstHandleIsShow_(AceType::MakeRefPtr<PropertyBool>(false)),
34       secondHandleIsShow_(AceType::MakeRefPtr<PropertyBool>(false)),
35       isHiddenHandle_(AceType::MakeRefPtr<PropertyBool>(false)),
36       isHandleLineShow_(AceType::MakeRefPtr<PropertyBool>(false)),
37       viewPort_(AceType::MakeRefPtr<PropertyRectF>(RectF(0, 0, 0, 0))),
38       firstHandle_(AceType::MakeRefPtr<PropertyRectF>(RectF(0, 0, 0, 0))),
39       secondHandle_(AceType::MakeRefPtr<PropertyRectF>(RectF(0, 0, 0, 0))),
40       handleColor_(AceType::MakeRefPtr<PropertyColor>(Color::BLACK)),
41       innerHandleColor_(AceType::MakeRefPtr<PropertyColor>(Color::BLACK)),
42       handleRadius_(AceType::MakeRefPtr<PropertyFloat>(0.0)),
43       innerHandleRadius_(AceType::MakeRefPtr<PropertyFloat>(0.0)),
44       handleOpacity_(AceType::MakeRefPtr<AnimatablePropertyFloat>(0.0))
45 {
46     AttachProperty(inShowArea_);
47     AttachProperty(handleReverse_);
48     AttachProperty(isSingleHandle_);
49     AttachProperty(firstHandleIsShow_);
50     AttachProperty(secondHandleIsShow_);
51     AttachProperty(isHiddenHandle_);
52     AttachProperty(isHandleLineShow_);
53     AttachProperty(viewPort_);
54     AttachProperty(firstHandle_);
55     AttachProperty(secondHandle_);
56     AttachProperty(handleColor_);
57     AttachProperty(innerHandleColor_);
58     AttachProperty(handleRadius_);
59     AttachProperty(innerHandleRadius_);
60     AttachProperty(handleOpacity_);
61 }
62 
onDraw(DrawingContext & drawingContext)63 void SelectOverlayContentModifier::onDraw(DrawingContext& drawingContext)
64 {
65     CHECK_NULL_VOID(!isUsingMouse_);
66     if (isHiddenHandle_->Get()) {
67         return;
68     }
69 
70     if (!inShowArea_->Get()) {
71         return;
72     }
73 
74     auto& canvas = drawingContext.canvas;
75     canvas.Save();
76     ClipViewPort(canvas);
77 
78     if (isSingleHandle_->Get()) {
79         // Paint one handle.
80         if (firstHandleIsShow_->Get()) {
81             PaintHandle(canvas, firstHandle_->Get(), false, isHandleLineShow_->Get());
82         } else if (secondHandleIsShow_->Get()) {
83             PaintHandle(canvas, secondHandle_->Get(), false, isHandleLineShow_->Get());
84         }
85     } else {
86         if (firstHandleIsShow_->Get()) {
87             PaintHandle(canvas, firstHandle_->Get(), !handleReverse_->Get());
88         }
89         if (secondHandleIsShow_->Get()) {
90             PaintHandle(canvas, secondHandle_->Get(), handleReverse_->Get());
91         }
92     }
93     canvas.Restore();
94 }
95 
ClipViewPort(RSCanvas & canvas)96 void SelectOverlayContentModifier::ClipViewPort(RSCanvas& canvas)
97 {
98     auto left = viewPort_->Get().Left();
99     auto top = viewPort_->Get().Top();
100     auto right = viewPort_->Get().Right();
101     auto bottom = viewPort_->Get().Bottom();
102     auto upHandle = firstHandle_->Get();
103     auto upHandleIsShow = firstHandleIsShow_->Get();
104     auto downHandle = secondHandle_->Get();
105     auto downHandleIsShow = secondHandleIsShow_->Get();
106     if (isSingleHandle_->Get()) {
107         upHandleIsShow = false;
108         downHandleIsShow = firstHandleIsShow_->Get() || secondHandleIsShow_->Get();
109         downHandle = firstHandleIsShow_->Get() ? firstHandle_->Get()
110                                                : (secondHandleIsShow_->Get() ? secondHandle_->Get() : downHandle);
111     } else if (handleReverse_->Get()) {
112         upHandle = secondHandle_->Get();
113         upHandleIsShow = secondHandleIsShow_->Get();
114         downHandle = firstHandle_->Get();
115         downHandleIsShow = firstHandleIsShow_->Get();
116     }
117     auto handleDiameter = handleRadius_->Get() * 2;
118     if (upHandleIsShow) {
119         auto halfWidth = upHandle.Width() / 2.0f;
120         left = std::min(upHandle.Left() + halfWidth - handleRadius_->Get(), left);
121         right = std::max(upHandle.Right() - halfWidth + handleRadius_->Get(), right);
122         top = std::min(upHandle.Top() - handleDiameter, top);
123         bottom = std::max(upHandle.Bottom(), bottom);
124     }
125     if (downHandleIsShow) {
126         auto halfWidth = downHandle.Width() / 2.0f;
127         left = std::min(downHandle.Left() + halfWidth - handleRadius_->Get(), left);
128         right = std::max(downHandle.Right() - halfWidth + handleRadius_->Get(), right);
129         top = std::min(downHandle.Top(), top);
130         bottom = std::max(downHandle.Bottom() + handleDiameter, bottom);
131     }
132     RSRect clipInnerRect = RSRect(left, top, right, bottom);
133     canvas.ClipRect(clipInnerRect, RSClipOp::INTERSECT);
134 }
135 
PaintHandle(RSCanvas & canvas,const RectF & handleRect,bool handleOnTop,bool isHandleLineShow)136 void SelectOverlayContentModifier::PaintHandle(
137     RSCanvas& canvas, const RectF& handleRect, bool handleOnTop, bool isHandleLineShow)
138 {
139     auto rectTopX = (handleRect.Left() + handleRect.Right()) / 2.0f;
140     auto centerOffset = OffsetF(rectTopX, 0.0f);
141     OffsetF startPoint(0.0, 0.0);
142     OffsetF endPoint(0.0, 0.0);
143     if (handleOnTop) {
144         centerOffset.SetY(handleRect.Top() - handleRadius_->Get());
145         startPoint.SetY(handleRadius_->Get() - 1.0);
146         endPoint.SetY(handleRadius_->Get() + handleRect.Height());
147     } else {
148         centerOffset.SetY(handleRect.Bottom() + handleRadius_->Get());
149         startPoint.SetY(-handleRadius_->Get() + 1.0f);
150         endPoint.SetY(-handleRadius_->Get() - handleRect.Height());
151     }
152 
153     canvas.Save();
154     RSBrush brush;
155     brush.SetAntiAlias(true);
156     canvas.Translate(centerOffset.GetX(), centerOffset.GetY());
157     // Paint outer circle.
158     Color handleColor = handleColor_->Get();
159     handleColor = handleColor.BlendOpacity(handleOpacity_->Get());
160     brush.SetColor(handleColor.GetValue());
161     canvas.AttachBrush(brush);
162     canvas.DrawCircle(RSPoint(0.0, 0.0), handleRadius_->Get());
163     canvas.DetachBrush();
164     // Paint inner circle.
165     Color innerHandleColor = innerHandleColor_->Get();
166     innerHandleColor = innerHandleColor.BlendOpacity(handleOpacity_->Get());
167     brush.SetColor(innerHandleColor.GetValue());
168     canvas.AttachBrush(brush);
169     canvas.DrawCircle(RSPoint(0.0, 0.0), innerHandleRadius_->Get());
170     canvas.DetachBrush();
171 
172     if (isHandleLineShow) {
173         RSPen pen;
174         pen.SetAntiAlias(true);
175         // Paint line of handle.
176         pen.SetColor(handleColor.GetValue());
177         pen.SetWidth(handleRect.Width());
178         pen.SetCapStyle(RSPen::CapStyle::ROUND_CAP);
179         canvas.AttachPen(pen);
180         canvas.DrawLine(RSPoint(startPoint.GetX(), startPoint.GetY()), RSPoint(endPoint.GetX(), endPoint.GetY()));
181         canvas.DetachPen();
182     }
183     canvas.Restore();
184 }
185 } // namespace OHOS::Ace::NG
186