• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-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 #ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_TEXT_PICKER_TEXT_PICKER_PATTERN_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_TEXT_PICKER_TEXT_PICKER_PATTERN_H
18 
19 #include <optional>
20 
21 #include "core/components/picker/picker_theme.h"
22 #include "core/components/dialog/dialog_theme.h"
23 #include "core/components_ng/pattern/linear_layout/linear_layout_pattern.h"
24 #include "core/components_ng/pattern/picker/picker_type_define.h"
25 #include "core/components_ng/pattern/text_picker/textpicker_row_accessibility_property.h"
26 #include "core/components_ng/pattern/text_picker/textpicker_event_hub.h"
27 #include "core/components_ng/pattern/text_picker/textpicker_layout_property.h"
28 #include "core/components_ng/pattern/text_picker/textpicker_paint_method.h"
29 #include "core/components_ng/pattern/text_picker/toss_animation_controller.h"
30 
31 namespace OHOS::Ace::NG {
32 class InspectorFilter;
33 using EventCallback = std::function<void(bool)>;
34 using ColumnChangeCallback = std::function<void(const RefPtr<FrameNode>&, bool, uint32_t, bool)>;
35 
36 namespace {
37 const Dimension TEXT_FOCUS_PAINT_WIDTH = 2.0_vp;
38 }
39 class TextPickerPattern : public LinearLayoutPattern {
40     DECLARE_ACE_TYPE(TextPickerPattern, LinearLayoutPattern);
41 
42 public:
TextPickerPattern()43     TextPickerPattern() : LinearLayoutPattern(false) {};
44 
45     ~TextPickerPattern() override = default;
46 
IsAtomicNode()47     bool IsAtomicNode() const override
48     {
49         return true;
50     }
51 
CreateEventHub()52     RefPtr<EventHub> CreateEventHub() override
53     {
54         return MakeRefPtr<TextPickerEventHub>();
55     }
56 
CreateLayoutProperty()57     RefPtr<LayoutProperty> CreateLayoutProperty() override
58     {
59         return MakeRefPtr<TextPickerLayoutProperty>();
60     }
61 
CreateAccessibilityProperty()62     RefPtr<AccessibilityProperty> CreateAccessibilityProperty() override
63     {
64         return MakeRefPtr<TextPickerRowAccessibilityProperty>();
65     }
66 
CreateNodePaintMethod()67     RefPtr<NodePaintMethod> CreateNodePaintMethod() override
68     {
69         auto textPickerPaintMethod = MakeRefPtr<TextPickerPaintMethod>(WeakClaim(this));
70         textPickerPaintMethod->SetDefaultPickerItemHeight(CalculateHeight());
71         textPickerPaintMethod->SetEnabled(enabled_);
72         return textPickerPaintMethod;
73     }
74 
CreateLayoutAlgorithm()75     RefPtr<LayoutAlgorithm> CreateLayoutAlgorithm() override
76     {
77         return MakeRefPtr<LinearLayoutAlgorithm>();
78     }
79 
80     void SetEventCallback(EventCallback&& value);
81 
82     void FireChangeEvent(bool refresh);
83 
84     void OnColumnsBuilding();
85 
86     void FlushOptions();
87 
88     void SetDefaultPickerItemHeight();
89 
90     std::map<uint32_t, RefPtr<FrameNode>> GetColumnNodes();
91 
92     RefPtr<FrameNode> GetColumnNode();
93 
94     uint32_t GetShowOptionCount() const;
95 
SetSelected(uint32_t value)96     void SetSelected(uint32_t value)
97     {
98         selectedIndex_ = value;
99     }
100 
GetSelected()101     uint32_t GetSelected() const
102     {
103         return selectedIndex_;
104     }
105 
SetRange(const std::vector<NG::RangeContent> & value)106     void SetRange(const std::vector<NG::RangeContent>& value)
107     {
108         if (value.empty()) {
109             return;
110         }
111         range_.clear();
112         for (size_t i = 0; i < value.size(); i++) {
113             RangeContent content;
114             content.icon_ = value[i].icon_;
115             content.text_ = value[i].text_;
116             range_.emplace_back(content);
117         }
118     }
119 
GetRange()120     std::vector<NG::RangeContent> GetRange() const
121     {
122         return range_;
123     }
124 
GetMultiOptions()125     std::vector<NG::TextCascadePickerOptions> GetMultiOptions() const
126     {
127         return cascadeOriginptions_;
128     }
129 
SetColumnsKind(uint32_t columnKind)130     void SetColumnsKind(uint32_t columnKind)
131     {
132         columnsKind_ = columnKind;
133     }
134 
ClearOption()135     void ClearOption()
136     {
137         options_.clear();
138     }
139 
AppendOption(const NG::RangeContent & value)140     void AppendOption(const NG::RangeContent& value)
141     {
142         options_.emplace_back(value);
143     }
144 
GetOptionCount()145     uint32_t GetOptionCount() const
146     {
147         return options_.size();
148     }
149 
150     std::string GetSelectedObject(bool isColumnChange, int32_t status = 0) const;
151 
GetOption(uint32_t index)152     std::string GetOption(uint32_t index) const
153     {
154         if (index >= GetOptionCount()) {
155             return "";
156         }
157         return options_[index].text_;
158     }
159 
SetBackgroundColor(const Color & color)160     void SetBackgroundColor(const Color& color)
161     {
162         if (backgroundColor_ == color) {
163             return;
164         }
165         auto host = GetHost();
166         CHECK_NULL_VOID(host);
167         backgroundColor_ = color;
168         host->MarkDirtyNode(PROPERTY_UPDATE_RENDER);
169     }
170 
GetBackgroundColor()171     Color GetBackgroundColor()
172     {
173         return backgroundColor_;
174     }
175 
GetFocusPattern()176     FocusPattern GetFocusPattern() const override
177     {
178         auto pipeline = PipelineBase::GetCurrentContext();
179         CHECK_NULL_RETURN(pipeline, FocusPattern());
180         auto pickerTheme = pipeline->GetTheme<PickerTheme>();
181         CHECK_NULL_RETURN(pickerTheme, FocusPattern());
182         auto focusColor = pickerTheme->GetFocusColor();
183 
184         FocusPaintParam focusPaintParams;
185         focusPaintParams.SetPaintColor(focusColor);
186         focusPaintParams.SetPaintWidth(TEXT_FOCUS_PAINT_WIDTH);
187 
188         return { FocusType::NODE, true, FocusStyleType::CUSTOM_REGION, focusPaintParams };
189     }
190 
191     void ToJsonValue(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const override;
192 
SetCascadeOptions(const std::vector<NG::TextCascadePickerOptions> & options,const std::vector<NG::TextCascadePickerOptions> & cascadeOptions)193     void SetCascadeOptions(const std::vector<NG::TextCascadePickerOptions>& options,
194         const std::vector<NG::TextCascadePickerOptions>& cascadeOptions)
195     {
196         cascadeOptions_.clear();
197         cascadeOriginptions_.clear();
198         for (auto& option : cascadeOptions) {
199             cascadeOptions_.emplace_back(std::move(option));
200         }
201         for (auto& option : options) {
202             cascadeOriginptions_.emplace_back(std::move(option));
203         }
204     }
205 
GetCascadeOptionCount()206     uint32_t GetCascadeOptionCount() const
207     {
208         return cascadeOptions_.size();
209     }
210 
GetOptionCount(const RefPtr<FrameNode> & frmeNode)211     uint32_t GetOptionCount(const RefPtr<FrameNode>& frmeNode)
212     {
213         uint32_t count = 0;
214         auto it = optionsWithNode_.find(frmeNode);
215         if (it != optionsWithNode_.end()) {
216             count = it->second.size();
217         }
218         return count;
219     }
220 
SetIsCascade(bool isCascade)221     void SetIsCascade(bool isCascade)
222     {
223         isCascade_ = isCascade;
224     }
225 
GetIsCascade()226     bool GetIsCascade() const
227     {
228         return isCascade_;
229     }
230 
SetConfirmNode(WeakPtr<FrameNode> buttonConfirmNode)231     void SetConfirmNode(WeakPtr<FrameNode> buttonConfirmNode)
232     {
233         weakButtonConfirm_ = buttonConfirmNode;
234     }
235 
SetCancelNode(WeakPtr<FrameNode> buttonCancelNode)236     void SetCancelNode(WeakPtr<FrameNode> buttonCancelNode)
237     {
238         weakButtonCancel_ = buttonCancelNode;
239     }
240 
SetForwardNode(WeakPtr<FrameNode> buttonForwardNode)241     void SetForwardNode(WeakPtr<FrameNode> buttonForwardNode)
242     {
243         weakButtonForward_ = buttonForwardNode;
244     }
245 
SetBackwardNode(WeakPtr<FrameNode> buttonBackwardNode)246     void SetBackwardNode(WeakPtr<FrameNode> buttonBackwardNode)
247     {
248         weakButtonBackward_ = buttonBackwardNode;
249     }
250 
251     void OnLanguageConfigurationUpdate() override;
252     void OnFontConfigurationUpdate() override;
253 
SetValues(const std::vector<std::string> & values)254     void SetValues(const std::vector<std::string>& values)
255     {
256         values_.clear();
257         for (auto& value : values) {
258             values_.emplace_back(value);
259         }
260     }
261 
GetValues()262     const std::vector<std::string>& GetValues()
263     {
264         return values_;
265     }
266 
GetSelecteds()267     const std::vector<uint32_t>& GetSelecteds()
268     {
269         return selecteds_;
270     }
271 
SetHasSelectAttr(bool value)272     void SetHasSelectAttr(bool value)
273     {
274         isHasSelectAttr_ = value;
275     }
276 
SetResizePickerItemHeight(double resizePickerItemHeight)277     void SetResizePickerItemHeight(double resizePickerItemHeight)
278     {
279         resizePickerItemHeight_ = resizePickerItemHeight;
280     }
281 
GetResizePickerItemHeight()282     double GetResizePickerItemHeight() const
283     {
284         return resizePickerItemHeight_;
285     }
286 
SetResizeFlag(bool resizeFlag)287     void SetResizeFlag(bool resizeFlag)
288     {
289         resizeFlag_ = resizeFlag;
290     }
291 
GetResizeFlag()292     bool GetResizeFlag() const
293     {
294         return resizeFlag_;
295     }
296 
SetIsShowInDialog(bool isShowInDialog)297     void SetIsShowInDialog(bool isShowInDialog)
298     {
299         isShowInDialog_ = isShowInDialog;
300     }
301 
GetIsShowInDialog()302     bool GetIsShowInDialog() const
303     {
304         return isShowInDialog_;
305     }
306 
GetDefaultPickerItemHeight()307     double GetDefaultPickerItemHeight() const
308     {
309         return defaultPickerItemHeight_;
310     }
311 
312     void SetSelecteds(const std::vector<uint32_t>& values);
313 
314     void HandleColumnChange(const RefPtr<FrameNode>& tag, bool isAdd, uint32_t index, bool needNotify);
315 
316     void SetChangeCallback(ColumnChangeCallback&& value);
317 
318     void ProcessCascadeOptions(const std::vector<NG::TextCascadePickerOptions>& options,
319         std::vector<NG::TextCascadePickerOptions>& reOptions, uint32_t index);
320 
321     size_t ProcessCascadeOptionDepth(const NG::TextCascadePickerOptions& option);
322 
323     void OnColorConfigurationUpdate() override;
324 
325     void OnDirectionConfigurationUpdate() override;
326 
SetContentRowNode(RefPtr<FrameNode> & contentRowNode)327     void SetContentRowNode(RefPtr<FrameNode>& contentRowNode)
328     {
329         contentRowNode_ = contentRowNode;
330     }
331 
SetPickerTag(bool isPicker)332     void SetPickerTag(bool isPicker)
333     {
334         isPicker_ = isPicker;
335     }
336 
337     void CheckAndUpdateColumnSize(SizeF& size, bool isNeedAdaptForAging = false);
338     bool NeedAdaptForAging();
339 
SetDivider(const ItemDivider & divider)340     void SetDivider(const ItemDivider& divider)
341     {
342         divider_ = divider;
343     }
344 
GetDivider()345     ItemDivider GetDivider()
346     {
347         return divider_;
348     }
349 
SetCustomDividerFlag(bool customDividerFlag)350     void SetCustomDividerFlag(bool customDividerFlag)
351     {
352         customDividerFlag_ = customDividerFlag;
353     }
354 
GetCustomDividerFlag()355     bool GetCustomDividerFlag()
356     {
357         return customDividerFlag_;
358     }
359 
SetGradientHeight(const Dimension & value)360     void SetGradientHeight(const Dimension& value)
361     {
362         value_ = value;
363     }
364 
GetGradientHeight()365     Dimension GetGradientHeight()
366     {
367         return value_;
368     }
369 
370     void SetCanLoop(bool isLoop);
371 
GetCanLoop()372     bool GetCanLoop()
373     {
374         return canloop_;
375     }
376 
SetRangeType(int32_t rangeType)377     void SetRangeType(int32_t rangeType)
378     {
379         rangeType_ = rangeType;
380     }
381 
GetRangeType()382     int32_t GetRangeType()
383     {
384         return rangeType_;
385     }
386 
HasUserDefinedDisappearFontFamily(bool isUserDefined)387     void HasUserDefinedDisappearFontFamily(bool isUserDefined)
388     {
389         hasUserDefinedDisappearFontFamily_ = isUserDefined;
390     }
391 
GetHasUserDefinedDisappearFontFamily()392     bool GetHasUserDefinedDisappearFontFamily()
393     {
394         return hasUserDefinedDisappearFontFamily_;
395     }
396 
HasUserDefinedNormalFontFamily(bool isUserDefined)397     void HasUserDefinedNormalFontFamily(bool isUserDefined)
398     {
399         hasUserDefinedNormalFontFamily_ = isUserDefined;
400     }
401 
GetHasUserDefinedNormalFontFamily()402     bool GetHasUserDefinedNormalFontFamily()
403     {
404         return hasUserDefinedNormalFontFamily_;
405     }
406 
HasUserDefinedSelectedFontFamily(bool isUserDefined)407     void HasUserDefinedSelectedFontFamily(bool isUserDefined)
408     {
409         hasUserDefinedSelectedFontFamily_ = isUserDefined;
410     }
411 
GetHasUserDefinedSelectedFontFamily()412     bool GetHasUserDefinedSelectedFontFamily()
413     {
414         return hasUserDefinedSelectedFontFamily_;
415     }
416 
updateFontConfigurationEvent(const std::function<void ()> & closeDialogEvent)417     void updateFontConfigurationEvent(const std::function<void()>& closeDialogEvent)
418     {
419         closeDialogEvent_ = closeDialogEvent;
420     }
421 
GetTextProperties()422     const PickerTextProperties& GetTextProperties() const
423     {
424         return textProperties_;
425     }
426 
SetTextProperties(const PickerTextProperties & properties)427     void SetTextProperties(const PickerTextProperties& properties)
428     {
429         textProperties_ = properties;
430         if (properties.disappearTextStyle_.fontSize.has_value() && properties.disappearTextStyle_.fontSize->IsValid()) {
431             isUserSetGradientFont_ = true;
432             gradientHeight_ = properties.disappearTextStyle_.fontSize.value();
433         }
434 
435         if (properties.normalTextStyle_.fontSize.has_value() && properties.normalTextStyle_.fontSize->IsValid()) {
436             isUserSetGradientFont_ = true;
437             gradientHeight_ = std::max(properties.normalTextStyle_.fontSize.value(), gradientHeight_);
438         }
439 
440         if (properties.selectedTextStyle_.fontSize.has_value() && properties.selectedTextStyle_.fontSize->IsValid()) {
441             isUserSetDividerSpacingFont_ = true;
442             dividerSpacing_ = properties.selectedTextStyle_.fontSize.value();
443         }
444     }
445 
GetIsUserSetDividerSpacingFont()446     bool GetIsUserSetDividerSpacingFont()
447     {
448         return isUserSetDividerSpacingFont_;
449     }
450 
GetIsUserSetGradientFont()451     bool GetIsUserSetGradientFont()
452     {
453         return isUserSetGradientFont_;
454     }
455 
GetDividerSpacing()456     Dimension GetDividerSpacing()
457     {
458         return dividerSpacing_;
459     }
460 
GetTextGradientHeight()461     Dimension GetTextGradientHeight()
462     {
463         return gradientHeight_;
464     }
465 
SetPaintDividerSpacing(float & value)466     void SetPaintDividerSpacing(float& value)
467     {
468         paintDividerSpacing_ = value;
469     }
470 
GetPaintDividerSpacing()471     float GetPaintDividerSpacing()
472     {
473         return paintDividerSpacing_;
474     }
475 
SetUserDefinedOpacity(double opacity)476     void SetUserDefinedOpacity(double opacity)
477     {
478         curOpacity_ = opacity;
479     }
480 
481 private:
482     void OnModifyDone() override;
483     void SetLayoutDirection(TextDirection textDirection);
484     void OnAttachToFrameNode() override;
485     bool OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper>& dirty, const DirtySwapConfig& config) override;
486 
487     void InitOnKeyEvent(const RefPtr<FocusHub>& focusHub);
488     bool OnKeyEvent(const KeyEvent& event);
489     bool HandleDirectionKey(KeyCode code);
490     double CalculateHeight();
491 
492     void InitDisabled();
493     void GetInnerFocusPaintRect(RoundRect& paintRect);
494     void PaintFocusState();
495     void SetButtonIdeaSize();
496     std::string GetRangeStr() const;
497     std::string GetOptionsMultiStr() const;
498     std::string GetOptionsMultiStrInternal() const;
499     std::string GetOptionsCascadeStr(
500         const std::vector<NG::TextCascadePickerOptions>& options) const;
501     bool ChangeCurrentOptionValue(NG::TextCascadePickerOptions& option,
502         uint32_t value, uint32_t curColumn, uint32_t replaceColumn);
503     void OnColumnsBuildingUnCascade();
504     void OnColumnsBuildingCascade();
505     std::string GetSelectedObjectMulti(const std::vector<std::string>& values,
506         const std::vector<uint32_t>& indexs, int32_t status) const;
507     void SupplementOption(const std::vector<NG::TextCascadePickerOptions>& reOptions,
508         std::vector<NG::RangeContent>& rangeContents, uint32_t patterIndex);
509     void ProcessCascadeOptionsValues(const std::vector<std::string>& rangeResultValue, uint32_t index);
510     void SetFocusCornerRadius(RoundRect& paintRect);
511     void UpdateConfirmButtonMargin(
512         const RefPtr<FrameNode>& buttonConfirmNode, const RefPtr<DialogTheme>& dialogTheme);
513     void UpdateCancelButtonMargin(
514         const RefPtr<FrameNode>& buttonCancelNode, const RefPtr<DialogTheme>& dialogTheme);
515     void CheckFocusID(int32_t childSize);
516     bool ParseDirectionKey(RefPtr<TextPickerColumnPattern>& textPickerColumnPattern, KeyCode& code, int32_t childSize);
517     RectF CalculatePaintRect(int32_t currentFocusIndex,
518         float centerX, float centerY, float piantRectWidth, float piantRectHeight, float columnWidth);
519 
520     bool enabled_ = true;
521     int32_t focusKeyID_ = 0;
522     double defaultPickerItemHeight_ = 0.0;
523     double resizePickerItemHeight_ = 0.0;
524     uint32_t selectedIndex_ = 0;
525     std::vector<NG::RangeContent> range_;
526     std::vector<NG::RangeContent> options_;
527     uint32_t columnsKind_ = 0;
528     std::vector<NG::TextCascadePickerOptions> cascadeOptions_;
529     std::map<WeakPtr<FrameNode>, std::vector<NG::RangeContent>> optionsWithNode_;
530     std::vector<NG::TextCascadePickerOptions> cascadeOriginptions_;
531     bool isCascade_ = false;
532     bool isHasSelectAttr_ = false;
533     WeakPtr<FrameNode> weakButtonConfirm_;
534     WeakPtr<FrameNode> weakButtonCancel_;
535     WeakPtr<FrameNode> weakButtonForward_;
536     WeakPtr<FrameNode> weakButtonBackward_;
537     std::vector<std::string> values_;
538     std::vector<uint32_t> selecteds_;
539     Color backgroundColor_ = Color::WHITE;
540     bool resizeFlag_ = false;
541     bool isShowInDialog_ = false;
542     bool canloop_ = true;
543 
544     // inner focus switch
545     bool operationOn_ = false;
546 
547     bool hasUserDefinedDisappearFontFamily_ = false;
548     bool hasUserDefinedNormalFontFamily_ = false;
549     bool hasUserDefinedSelectedFontFamily_ = false;
550 
551     double curOpacity_ = 1.0;
552 
553     ACE_DISALLOW_COPY_AND_MOVE(TextPickerPattern);
554 
555     WeakPtr<NG::FrameNode> contentRowNode_;
556     bool isPicker_ = true;
557     bool isFiredSelectsChange_ = false;
558     std::optional<std::string> firedSelectsStr_;
559 
560     ItemDivider divider_;
561     bool customDividerFlag_ = false;
562     Dimension value_;
563     int32_t rangeType_ = 0;
564     std::function<void()> closeDialogEvent_;
565     bool isUserSetDividerSpacingFont_ = false;
566     bool isUserSetGradientFont_ = false;
567     Dimension gradientHeight_;
568     Dimension dividerSpacing_;
569     float paintDividerSpacing_ = 1.0f;
570     bool isNeedUpdateSelectedIndex_ = true;
571     PickerTextProperties textProperties_;
572 };
573 } // namespace OHOS::Ace::NG
574 
575 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_TEXT_PICKER_TEXT_PICKER_PATTERN_H
576